C中的整数指针的常量值赋值适用于此情况

时间:2017-09-04 14:34:33

标签: c pointers

我得到了一个令人惊讶的观察,以下代码正在获得分段错误

#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。

3 个答案:

答案 0 :(得分:1)

首先,由于未初始化指针i的取消引用,两者代码段都会导致undefined behavior

在您的第一种情况下,您尝试取消引用未初始化的指针i,因此这是未定义的行为。

你正在做

 *i = 100;

但请想一想i指向哪里?可能是某些内存位置无法从进程访问,因此它是无效的内存访问。这会触发UB。

同样在第二个片段中也是如此。

但是,如果您从第二个代码段删除了i的使用情况,那就没问题了。

在建议的更改之后,在第二个片段中,您将字符串文字的起始地址存储到指针变量中,即分配它。所以,这完全可以。

对于像

这样的陈述
  str = "Hello";

你在这里 defererencing str,而是将指针值分配给str,这完全没问题。

那就是说,

  • 根据C标准,对于托管环境,void main()不是一致的签名,您必须至少使用int main(void)
  • printf("%u\n",i);这样的语句也会以自己的方式调用未定义的行为。如果要打印指针,必须使用%p格式说明符并将参数转换为void*

答案 1 :(得分:0)

由于以下原因,您的两个程序都会导致未定义的行为。因此无法获得正确的结果。

1)取消引用未初始化的指针*i = 100;是未定义的行为。在您的两个示例中,您在初始化之前取消引用指针i。因此,首先使用&运算符初始化指针,然后在代码中使用它。

2)使用无符号的转换说明符打印指针值。您应该使用%p代替。

答案 2 :(得分:0)

i尚未初始化为特别指向任何内存位置,因此它不是有效指针值。尝试通过无效指针进行写入会导致未定义的行为,这意味着结果可能是任何内容 - 您的代码可能会彻底崩溃,可能会损坏数据,可能会出现乱码输出,或者可能看起来与没有问题。