未初始化指针的可能输出

时间:2014-06-20 07:18:52

标签: c pointers casting segmentation-fault

我有以下代码:

main(){
   char *buf;
   gets(buf);
   printf("Got %x\n",*(unsigned int *)buf);
}

我把01234放在stdin上用于缓冲区。我认为总会出现分段错误,但我的讲师说有时可以打印“Got 33323130”作为输出。

有人能解释我为什么吗?

2 个答案:

答案 0 :(得分:3)

正如其他人所说,buf未定义。由于它是在堆栈上声明的,因此它的内容将取决于在调用main之前可能在堆栈上留下的内容。通常,在调用main之前会发生很多事情(C运行时初始化),所以尽管在程序启动时堆栈最初为零(这是防止数据“泄漏”的操作系统安全要求),但很有可能调用main时为buf指针分配的堆栈区域将不再为零。它可以通过环境变量,参数,编译选项等来实现。

如果buf恰好指向可写入的内存位置,则程序不会发生段错误,您将能够成功写入该位置。在这种情况下,您将在小端机器(例如基于x86的机器)上看到“Got 33323130”作为输出。在大端机器上你会看到“得到30313233”。

答案 1 :(得分:2)

你在做什么调用"未定义的行为"这意味着(ISO / IEC 9899:1999,3.4.3):

  

行为,使用不可移植或错误的程序构造或   错误的数据,本国际标准没有规定   要求

     

注意可能的未定义行为包括忽略   这种情况完全具有不可预测的结果,表现得很好   在翻译或程序执行过程中以文件的方式   环境的特征(有或没有发行   诊断消息),终止翻译或执行(用   发布诊断信息。)

您的编译器和程序可以执行任何操作。

为什么它是未定义的行为?因为在7.1.4("使用库函数")中,C标准要求:

  

如果函数参数被描述为数组,则指针   实际传递给函数的值应该是全部   地址计算和对象的访问[...]   事实是有效的。

和4(" Conformance"):

  

如果违反了''应'或''不得''要求[...],则行为未定义。