【发布时间】:2017-05-18 23:54:14
【问题描述】:
我有这个代码:
#include <cstdio>
int foo[100];
int main()
{
for(int i=0;i<10000;i++)
foo[i]=10000;
}
使用 GDB 进行调试会得到令人惊讶的结果:
[New Thread 23684.0x59b4]
[New Thread 23684.0x5c0c]
[New Thread 23684.0x541c]
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401564 in main () at C:\Users\DARREN\Documents\Visual Studio
2017\Projects\Untitled1.cpp:9
warning: Source file is more recent than executable.
9 }
(gdb) print i
$1 = 4080
(gdb)
现在,我知道声明 foo[i]=10000 导致了错误,但我声明 foo 的大小仅为 100。为什么i的值会在错误发生之前这么大?
感谢任何解释。
【问题讨论】:
-
越界访问元素是“未定义的行为”,这意味着任何事情都可能发生。 “直到错误发生很久之后才报告任何问题”是“任何事情”的一种可能结果。
-
不幸的是,未定义的行为不一定会导致明显的问题。由于
que[]是数据段的一部分,因此似乎有很多有效的内存位置可以在遇到无效内存位置之前被读取。 -
C++ 遵循“只为你使用的东西付费”的理念。一个正确的程序没有缓冲区溢出,因此检查缓冲区溢出是他们不应该付出的代价。结果是零检查,程序将继续运行,直到可能由溢出导致的某些事情导致它停止。
-
使用
std::vector代替普通数组,使用.at(size_t pos)代替下标运算符。这样你会在越界时遇到异常。 -
我不认为这是重复的,因为链接的答案没有回答问题,这就是为什么在偏移 4080 之前没有错误。只是说“那是未定义的行为”没有回答这个问题,不仅仅是“问:为什么天空是蓝色的?答:因为它不是黄色的”
标签: c++ arrays debugging segmentation-fault