我知道你可以读过一个数组的结尾 - 我现在想知道你是否可以通过执行读操作来解决错误。
int someints[100];
std::cerr << someints[100] << std::endl; //This is 1 past the end of the array.
第二行是否会导致段错?还是会打印出乱码?另外,如果我改变了那个内存,可能会导致特定行上的段错误,或者只有在其他人试图使用意外更改的内存时才会发生错误?
答案 0 :(得分:9)
这是未定义的行为,完全取决于操作系统为进程安排的虚拟内存布局。通常你可以:
如果someints
是堆栈上的数组并且是最后一个声明的变量,那么很可能会从堆栈顶部获得一些乱码或(非常不可能)调用可能让操作系统出现的页面错误使用SIGSEGV
调整堆栈大小或终止您的流程。
想象一下,你在阵列后面声明了一个int
:
int someints[100];
int on_top_of_stack = 42;
std::cerr << someints[100] << std::endl;
然后很可能该程序应该打印42
,除非编译器以某种方式重新排列堆栈上的声明顺序。
答案 1 :(得分:4)
是的,如果程序无法访问该地址的内存,则可能会出现段错误。在你的情况下,它不太可能在堆栈上分配数组,并且只有100个字节长,堆栈大小要大得多(即Linux 2.4.X上每个线程8 MB),因此会有未初始化的数据。但在某些情况下它可能会崩溃。在任何一种情况下,此代码都是错误的,像Valgrind这样的分析器应该能够帮助您排除故障。
答案 2 :(得分:2)
第二行可能导致字面上任何发生,并且就语言规范而言仍然是正确的。它可以打印乱码,它可能因分段故障或其他原因而崩溃,它可能导致整个东海岸的电力消失,或者它可能导致规范demons to fly out of your nose ......
这是undefined behaviour的魔力。