我有这个看起来像的程序。
int indexLength;
char *args[1024];
while(args[indexLength])
indexLength++;
如果我在计算机上运行程序,while循环行给了我一个段错误...而indexLength取一些荒谬的任意值。 但是如果我在家里的linux机器上运行该程序,则没有段错误,我的程序正常运行。
我能想到的两台机器之间的唯一区别就是工作中的那台机器有gcc4.7 redhat版本,并且正在运行Fedora OS,而我家的机器已经从ppa存储库下载了gcc4.7,并且正在运行ubuntu OS。 但是,我不相信这是唯一的区别!它能是什么?
编辑:抱歉,我忘了提及。如果我初始化indexLength = 0,那么段落故障就会在计算机上消失。答案 0 :(得分:5)
从未初始化的内存中读取未定义的行为。默认情况下,变量不会初始化,因此indexLength
可以在分配变量之前获取任何值。由于行为未定义,程序可能会在某些计算机上运行,而在其他计算机上崩溃。
此外,即使将indexLength
初始化为零也无法修复未定义的行为,因为args
仍然未初始化。这意味着程序可能不会在到达数组末尾时停止,并且访问超过分配区域末尾的值。当然,为了做到这一点,1024个项目的数组中的所有值必须为非零,因此在到达数组末尾之前,有利于停止。但是,为了修复此未定义的行为,您需要在访问值之前检查索引。
答案 1 :(得分:3)
您的代码调用未定义的行为
args
未初始化,因此每个元素都包含不可预测的值。也许你会在堆栈的下一个4k找到一个NULL指针并退出循环;也许你不会,你会读到数组的末尾indexLength
未初始化,因此您可以立即阅读超出阵列末尾的方式args
结尾的效果也是不可预测的。这包括可能崩溃,比如说在达到流程的可读内存限制之前没有找到零字尽管初次出现,但设置indexLength=0
实际上并没有使您的代码安全。你还在读取未初始化的内存,所以依赖于在args
中找到一个NULL元素。没有办法保证你会发现这个。如果在到达数组末尾之前没有退出循环,则会返回到未定义的行为,因此程序可能会在任何进一步的迭代中崩溃。