#include <iostream>
using namespace std;
int a[4];
int main(){
int b=7;
cout<<a[b]<<endl;
return 0;
}
我试图访问未分配的内存。所以我希望输出是一个分段错误,而输出是一些垃圾值。
后来我将'b'增加到1000,现在输出是'Segmentation fault'。这种行为有特定原因吗?
我正在使用gcc-4.3.2编译器。
答案 0 :(得分:6)
a[7]
可能不在其可访问空间之外,但a[1000]
肯定是。{1}}。但即使前者会爆发,当你最不期望它时;)
答案 1 :(得分:2)
只有在访问操作系统不允许您访问的内存时,才会发生分段错误。
但是,您可以访问已经授予您的内存,而不是您期望的内存,例如指向堆栈中较早或较晚的内存地址。但是,你不能依赖于一致性,因为本地存储的变量放置在堆栈上的方式由编译器根据不同的优化来决定 - 从调试到发布,代码更改等等。
但是,如果你看到类似的东西,'为什么访问这个变量会给我垃圾,但总是同样的垃圾?'你可能是无意中偷看你不应该在堆栈的某些部分。
答案 2 :(得分:1)
这是未定义的行为所以任何事情都可能发生,你无法分辨。检查 this out(对于C ++),以了解未定义行为,未指定行为和实现定义行为之间的区别。
附录J中的C -**ISO C9899**
清楚地谈到了这一点。
修改强>
C ++ - N3485 ISO/IEC
部分1.9.2
,1.9.3
,1.9.4
讨论了上述行为。
答案 3 :(得分:0)
超出界限访问是未定义的行为。它可以访问进程空间中的任意内存。如果在进程地址空间(可能在内核中)未分配访问的内存,则程序将因分段错误而崩溃。在这种情况下,故障将帮助您识别问题,如果幸运将导致崩溃,否则它可能会被忽视,并会在程序破坏内存后得到一些错误,然后很难跟踪。未分配的[1000]的概率更大,因此崩溃。内存分配在页面中。
答案 4 :(得分:0)
不需要未定义的行为来导致段错误。请考虑int i = INT_MAX + 1;
以获取通常不会导致段错误的未定义行为的另一个示例。