我得到了一个令人惊讶的观察,以下代码正在获得分段错误
#include<stdio.h>
void main() {
int *i;
*i = 100;
printf("%u\n",i);
printf("%d\n",*i);
}
但不是下面的那个。
#include<stdio.h>
void main() {
char* str;
int *i;
*i=100;
str = "Hello";
printf("%u\n",i);
printf("%s %d\n",str,*i);
}
有人可以解释这种行为吗?我正在使用gcc。
答案 0 :(得分:1)
首先,由于未初始化指针i
的取消引用,两者代码段都会导致undefined behavior。
在您的第一种情况下,您尝试取消引用未初始化的指针i
,因此这是未定义的行为。
你正在做
*i = 100;
但请想一想i
指向哪里?可能是某些内存位置无法从进程访问,因此它是无效的内存访问。这会触发UB。
同样在第二个片段中也是如此。
但是,如果您从第二个代码段删除了i
的使用情况,那就没问题了。
在建议的更改之后,在第二个片段中,您将字符串文字的起始地址存储到指针变量中,即分配它。所以,这完全可以。
对于像
这样的陈述 str = "Hello";
你在这里不 defererencing str
,而是将指针值分配给str
,这完全没问题。
那就是说,
void main()
不是一致的签名,您必须至少使用int main(void)
。printf("%u\n",i);
这样的语句也会以自己的方式调用未定义的行为。如果要打印指针,必须使用%p
格式说明符并将参数转换为void*
。答案 1 :(得分:0)
由于以下原因,您的两个程序都会导致未定义的行为。因此无法获得正确的结果。
1)取消引用未初始化的指针*i = 100;
是未定义的行为。在您的两个示例中,您在初始化之前取消引用指针i
。因此,首先使用&
运算符初始化指针,然后在代码中使用它。
2)使用无符号的转换说明符打印指针值。您应该使用%p
代替。
答案 2 :(得分:0)
i
尚未初始化为特别指向任何内存位置,因此它不是有效指针值。尝试通过无效指针进行写入会导致未定义的行为,这意味着结果可能是任何内容 - 您的代码可能会彻底崩溃,可能会损坏数据,可能会出现乱码输出,或者可能看起来与没有问题。