我有以下代码:
main(){
char *buf;
gets(buf);
printf("Got %x\n",*(unsigned int *)buf);
}
我把01234放在stdin上用于缓冲区。我认为总会出现分段错误,但我的讲师说有时可以打印“Got 33323130”作为输出。
有人能解释我为什么吗?
答案 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"):
如果违反了''应'或''不得''要求[...],则行为未定义。