为什么下面的代码不产生分段错误?
Why doesn't the following code produce a segmentation fault?
#include <iostream>
using namespace std;
int a[4];
int main(){
int b=7;
cout<<a[b]<<endl;
return 0;
}
我试图访问未分配的内存。所以我期望输出是一个分割错误,而不是输出是一些垃圾值。
后来我将'b'增加到1000,现在输出是'Segmentation fault'。这种行为有什么特别的原因吗?
如果您试图访问不存在的内存地址(在进程的地址空间之外),可能会抛出分段错误。
在这种情况下, a[7]
可能不在其可访问空间之外,但a[1000]
肯定在。但即使是前者也会在你最意想不到的时候爆炸;)
只有在访问操作系统不允许访问的内存时才会出现分段错误。
然而,你可以访问内存,虽然它不是你期望的,已经授予你,例如内存地址指向较早或较晚的堆栈。但是你不能指望它是一致的,因为本地存储的变量如何放在堆栈上是由编译器根据神秘的优化来决定的,这些优化会随着代码的变化而变化——从调试到发布,等等。
但是如果你曾经看到过这样的情况,"为什么访问这个变量会给我垃圾,但总是相同的垃圾?"
这是未定义的行为,所以任何事情都可能发生,你只是不能告诉。查看this out (c++)以了解未定义行为,未指定行为和实现定义行为之间的区别。
附件JC - **ISO C9899**
对此有明确论述。
编辑
c++ - N3485 ISO/IEC
在1.9.2
, 1.9.3
, 1.9.4
章节中讨论了上述行为
越界访问是未定义的行为。它可以访问进程空间中的任意内存。如果访问的内存没有分配或不在进程地址空间中(可能在内核中),那么您的程序将因分段错误而崩溃。在这种情况下,错误将帮助您识别问题,如果幸运的话会导致崩溃,否则它可能会被忽视,并且会在程序中得到一些错误,这些错误会破坏内存,然后难以跟踪。a[1000]未分配的概率更高,从而导致崩溃。
未定义的行为不需要引起段错误。考虑int i = INT_MAX + 1;
的另一个未定义行为的例子,它通常不会导致段错误。
- 在某些循环内使用vector.push_back时出现分段错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 当我的阵列太大时出现分段错误
- 分段错误当我试图运行程序时出错
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 尝试使用集合函数时出现分段错误
- 我无法缩小此分段错误的原因
- g++的分段错误(在NaN上使用to_string两次时)
- 我是如何在这段代码中出现分段错误的
- 创建结构的数组时遇到分段错误
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 在 c++ 中实现 Trie 时出现分段错误
- 为什么 fstream 在打开带有格式的文件时会导致分段错误?
- 为什么我遇到分段错误?
- 动态类的分段错误(家庭作业问题)
- 分段错误 - 读取初始化指针的数组
- 如何摆脱C ++中的分段错误错误?
- 使用 CTYPE 时出现分段错误
- 为什么代码给出分段错误?