繁体   English   中英

为什么这行代码会导致计算机死机?

[英]Why does this line of code cause a computer to crash?

为什么这行代码会导致电脑死机? 在内存特定级别会发生什么?

for(int *p=0; ;*(p++)=0)
    ;

我在 Everything2 上找到了“答案”,但我想要一个具体的技术答案。

这段代码只是正式地将 integer 指针设置为 null,然后将 0 写入它指向的 integer 并递增指针,永远循环。

null 指针没有指向任何东西,因此向它写入 0 是未定义的行为(即标准没有说明应该发生什么)。 此外,您不允许在 arrays 之外使用指针算法,因此即使只是增量也是未定义的行为。

未定义的行为意味着编译器和库作者根本不需要关心这些情况,系统仍然是有效的 C/C++ 实现。 如果程序员做了任何归类为未定义行为的事情,那么无论发生什么,他/她都不能责怪编译器和库作者。 输入未定义行为 realm 的程序员不能指望出现错误消息或崩溃,但如果收到错误消息或崩溃则不能抱怨(即使是稍后执行的一百万条指令)。

在 null 指针表示为零且不支持 memory 保护的系统上,效果或此类循环可能会开始擦除所有可寻址的 memory,直到 memory 的某些重要部分(如中断表)损坏或直到代码在代码本身上写零,自我毁灭。 在具有 memory 保护的其他系统(当今最常见的桌面系统)上,执行可能会在第一次写入操作时停止。

毫无疑问,问题的原因是p没有分配到合理的地址。

如果在写入指针指向的位置之前没有正确初始化指针,它可能会做Bad Things ™。

它可能只是段错误,或者它可能会覆盖一些重要的东西,比如函数的返回地址,在 function 尝试返回之前不会发生段错误。


在 1980 年代,与我共事的一位理论家为 8086 编写了一个程序,每秒一次,在随机计算的地址写入一个随机数据字。 计算机是一个带有看门狗保护的进程 controller 和各种类型的 output。问题是:系统在停止有用功能之前要运行多长时间? 答案是小时和小时 这生动地展示了 memory 的大部分内容很少被访问。

可能会导致操作系统崩溃,或者它可能会做任何其他事情。 您正在调用未定义的行为。 您不拥有地址0处的 memory,也不拥有它后面的 memory。 你只是在打不属于你的 memory。

它的工作原理是覆盖所有地址的所有 memory,从 0 开始向上。 最终它会覆盖一些重要的东西。

在任何现代系统上,这只会使您的程序崩溃,而不会使整个计算机崩溃。 从 1985 年左右开始设计的 CPU 具有称为虚拟 memory的功能,它允许操作系统重定向程序的 memory 地址。 大多数地址根本不指向任何地方,这意味着尝试访问它们只会使您的程序崩溃 - 而指向某处的地址将指向分配给您的程序的 memory,因此您只能通过以下方式使您自己的程序崩溃惹他们。

在更旧的系统上(请记住,早于 1985 年)。 没有这样的保护,这个循环可以访问分配给其他程序和操作系统的 memory 地址。

循环没有必要解释什么是错误的。 我们可以简单地只看第一次迭代。

int *p = 0; // Declare a null pointer
*p = 0;     // Write to null pointer, causing UB

第二行导致未定义的行为,因为当您写入 null 指针时会发生这种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM