指向数组的指针
Pointer to the array
int (*a)[10] = NULL; // initilaized to NULL pointer
printf("a :: %p\n", a); // print nil
printf("*a :: %p\n", *a); // seg fault??
return 0;
我使用 gcc 在我的 x86 代码上执行了这段代码,并且编译没有任何错误。
我期待
一个::(无)
分段错误
但它实际上打印出来了
一个::(无)
*a :: (无)
为什么这里引用空指针不会导致段错误?
这是因为这是未定义的行为,任何编译器甚至不同版本的编译器都可能发生任何事情。
您正在使用 gcc,而 gcc 生成的代码只是将 NULL(零)移动到 rax,而不会出现段错误。
mov QWORD PTR [rbp-8], 0
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rbp-16], rax
您可以在
查看不同版本 gcc 的 C 程序的汇编输出
一般的原因是取消对数组指针的引用不会读取任何内存,结果是一个具有相同地址的数组 - 结果只是不同的类型。
尽管如此,该行为仍未定义。
请注意,您使用了 %p
,但您可以将 %s
用于第二个(使用 char (*a)[10] = NULL;
),这将有更多未定义的行为,但仍然 GCC/Glibc printf
会 经常 打印 (nil)
而不是崩溃。
int (*a)[10] = NULL; // initilaized to NULL pointer
printf("a :: %p\n", a); // print nil
printf("*a :: %p\n", *a); // seg fault??
return 0;
我使用 gcc 在我的 x86 代码上执行了这段代码,并且编译没有任何错误。
我期待
一个::(无)
分段错误
但它实际上打印出来了
一个::(无)
*a :: (无)
为什么这里引用空指针不会导致段错误?
这是因为这是未定义的行为,任何编译器甚至不同版本的编译器都可能发生任何事情。
您正在使用 gcc,而 gcc 生成的代码只是将 NULL(零)移动到 rax,而不会出现段错误。
mov QWORD PTR [rbp-8], 0
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rbp-16], rax
您可以在
查看不同版本 gcc 的 C 程序的汇编输出一般的原因是取消对数组指针的引用不会读取任何内存,结果是一个具有相同地址的数组 - 结果只是不同的类型。
尽管如此,该行为仍未定义。
请注意,您使用了 %p
,但您可以将 %s
用于第二个(使用 char (*a)[10] = NULL;
),这将有更多未定义的行为,但仍然 GCC/Glibc printf
会 经常 打印 (nil)
而不是崩溃。