英文:
undefined behaviour when trying to print array elements
问题
这段代码的目标是通过printf
打印出二维数组中的字符串,但输出结果确实很奇怪。输出如下:
>
> abcd
> efgh
> klmn
> �=3�
>
>
>
>
>
>
> I8V
>
>
> 3�
>
> �
> ��.m�
> �
>
> ?3�
>
> zI8V
>
>
> ��HU�yԁB��7x
> �yԁB��7x
> B��7x
>
>
>
>
>
>
>
> �
>
> ���
>
>
>
> �yI8V
>
> I8V
>
>
>
>
>
>
>
>
>
> ��p��C�x86_64
> �C�x86_64
> x86_64
> 4
>
>
> /strcat
> at
> ELL=/bin/bash
> bin/bash
> ash
> ESSION_MANAGER=local/kali:@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> N_MANAGER=local/kali:@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> AGER=local/kali:@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> local/kali:@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> /kali:@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> :@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> p/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> E-unix/836,unix/kali:/tmp/.ICE-unix/836
> x/836,unix/kali:/tmp/.ICE-unix/836
> ,unix/kali:/tmp/.ICE-unix/836
> /kali:/tmp/.ICE-unix/836
> :/tmp/.ICE-unix/836
> /.ICE-unix/836
> -unix/836
> /836
> WINDOWID=0
> WID=0
>
> CCESSIBILITY=1
> IBILITY=1
> TY=1
> COLORTERM=truecolor
> TERM=truecolor
> truecolor
> olor
> XDG_CONFIG_DIRS=/etc/xdg
> ONFIG_DIRS=/etc/xdg
> _DIRS=/etc/xdg
> =/etc/xdg
> /xdg
> XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0
> ESSION_PATH=/org/freedesktop/DisplayManager/Session0
> N_PATH=/org/freedesktop/DisplayManager/Session0
> H=/org/freedesktop/DisplayManager/Session0
> g/freedesktop/DisplayManager/Session0
> edesktop/DisplayManager/Session0
> top/DisplayManager/Session0
> isplayManager/Session0
> yManager/Session0
> ger/Session0
这种输出是由于代码中的错误导致的。循环条件 x<=x+2
是不正确的,它导致了无效的内存访问。正确的循环条件应该是 x<=names+2
,这样就可以正确迭代数组并打印字符串。
希望这个解释有帮助。如果您还有其他问题,请随时提出。
英文:
#include<stdio.h>
int main(){
char names[3][5]={{'a','b','c','d','\0'},{'e','f','g','h','\0'},{'k','l','m','n','\0'}};
char (*x)[5];
for(x=names;x<=x+2;x++){
printf("%s\n",*x);
}
}
the goals of this code is to printf
the strings in this 2d array, but the output is really weird. It is the first time I see something like this.
ouptut:
>
> abcd
> efgh
> klmn
> �=3�
>
>
>
>
>
>
> I8V
>
>
> 3�
>
> �
> ��.m�
> �
>
> ?3�
>
> zI8V
>
>
> ��HU�yԁB��7x
> �yԁB��7x
> B��7x
>
>
>
>
>
>
>
> �
>
> ���
>
>
>
> �yI8V
>
> I8V
>
>
>
>
>
>
>
>
>
> ��p��C�x86_64
> �C�x86_64
> x86_64
> 4
>
>
> /strcat
> at
> ELL=/bin/bash
> bin/bash
> ash
> ESSION_MANAGER=local/kali:@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> N_MANAGER=local/kali:@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> AGER=local/kali:@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> local/kali:@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> /kali:@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> :@/tmp/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> p/.ICE-unix/836,unix/kali:/tmp/.ICE-unix/836
> E-unix/836,unix/kali:/tmp/.ICE-unix/836
> x/836,unix/kali:/tmp/.ICE-unix/836
> ,unix/kali:/tmp/.ICE-unix/836
> /kali:/tmp/.ICE-unix/836
> :/tmp/.ICE-unix/836
> /.ICE-unix/836
> -unix/836
> /836
> WINDOWID=0
> WID=0
>
> CCESSIBILITY=1
> IBILITY=1
> TY=1
> COLORTERM=truecolor
> TERM=truecolor
> truecolor
> olor
> XDG_CONFIG_DIRS=/etc/xdg
> ONFIG_DIRS=/etc/xdg
> _DIRS=/etc/xdg
> =/etc/xdg
> /xdg
> XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0
> ESSION_PATH=/org/freedesktop/DisplayManager/Session0
> N_PATH=/org/freedesktop/DisplayManager/Session0
> H=/org/freedesktop/DisplayManager/Session0
> g/freedesktop/DisplayManager/Session0
> edesktop/DisplayManager/Session0
> top/DisplayManager/Session0
> isplayManager/Session0
> yManager/Session0
> ger/Session0
Could you explain the meaning of that output and why am I getting it?
edit
Now I understand where I made the mistake, but anyway I want to know where does that output come.
答案1
得分: 1
The problem is that you compare the value of x
to itself.
The expression x <= x + 2
can never be false
.
The value of x
is reevaluated for each occurrence in the expression, not just the left side.
You should store the result of x + 2
in a variable and use that variable on the right side of the expression.
英文:
#include <stdio.h>
int main(){
char names[3][5] = {{'a','b','c','d','\0'},{'e','f','g','h','\0'},{'k','l','m','n','\0'}};
char (*x)[5];
// +- HERE
// |
for (x = names; x <= x + 2; x++) {
printf("%s\n", *x);
}
}
The problem is that you compare the value of x
to itself.
The expression x <= x + 2
can never be false
.
The value of x
is reevaluated for each occurrence in the expression, not just the left side.
You should store the result of x + 2
in a variable and use that variable on the right side of the expression.
答案2
得分: 1
您好,以下是您要翻译的文本:
You wondered where those "weird strings" came from. They look like fragments of a typical Unix/Linux process environment, which consists of a list of name/value pairs known as environment variables.
Normally you access these strings in a C program by using the getenv function, but they are contained in an array of strings (similar to your program's arguments argv) copied into your process's address space when it is exec'ed. Under most Unix-like systems you can peek at the raw environment strings using code like the following:
#include <stdio.h>
int main(int argc, char **argv, char **envp)
{
char *p;
for(p = *envp;; p++) putchar(*p);
}
or
extern char **environ;
int main()
{
char *p;
for(p = *environ;; p++) putchar(*p);
}
Those are both quickly and crudely written, and sail off the end of the environment and eventually crash (as indeed your program did). A cleaner way of printing the environment would be:
char **v;
char *p;
for(v = environ; *v != NULL; v++) {
for(p = *v; *p != 'char **v;
char *p;
for(v = environ; *v != NULL; v++) {
for(p = *v; *p != '\0'; p++) putchar(*p);
putchar('\n');
}
'; p++) putchar(*p);
putchar('\n');
}
英文:
You wondered where those "weird strings" came from. They look like fragments of a typical Unix/Linux process environment, which consists of a list of name/value pairs known as environment variables.
Normally you access these strings in a C program by using the getenv
function, but they are contained in an array of strings (similar to your program's arguments argv
) copied in to your process's address space when it is exec'ed. Under most Unix-like systems you can peek at the raw environment strings using code like the following:
#include <stdio.h>
int main(int argc, char **argv, char **envp)
{
char *p;
for(p = *envp;; p++) putchar(*p);
}
or
extern char **environ;
int main()
{
char *p;
for(p = *environ;; p++) putchar(*p);
}
Those are both quickly and crudely written, and sail off the end of the environment and eventually crash (as indeed your program did). A cleaner way of printing the environment would be
char **v;
char *p;
for(v = environ; *v != NULL; v++) {
for(p = *v; *p != 'char **v;
char *p;
for(v = environ; *v != NULL; v++) {
for(p = *v; *p != '\0'; p++) putchar(*p);
putchar('\n');
}
'; p++) putchar(*p);
putchar('\n');
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论