为什么当我在数组的末尾之外写东西时,我没有得到一个分段错误呢?

为什么当我在数组的末尾之外写东西时,我没有得到一个分段错误呢?

为什么我编译时没有出现错误?

#include <iostream>using namespace std;int main(){
    int *a = new int[2];
    // int a[2]; // even this is not giving error
    a[0] = 0;
    a[1] = 1;
    a[2] = 2;
    a[3] = 3;
    a[100] = 4;
    int b;

    return 0;}

有人能解释一下为什么会发生这种事吗。(事先谢谢。)


呼如林
浏览 356回答 3
3回答

犯罪嫌疑人X

我猜您来自Java或类似Java的语言,一旦走出数组的边界,就会得到“数组索引越界”异常。好的,C对你有更多的期望;它节省了你想要的空间,但它不检查你是否超出了节省的空间的边界。正如上面提到的那样,一旦您这样做了,程序就会有令人恐惧的未定义的行为。记住,将来如果你的程序中有一个bug,你似乎找不到它,当你检查代码/调试它时,一切看起来都很好,你很有可能“超出范围”并访问一个未分配的位置。

慕的地10843

因为未定义的行为=任何事情都可能发生。不幸的是,它没有崩溃,这种行为可能隐藏错误。至于a定义两次-这是编译器中的一个错误。

慕田峪4524236

声明两个名为a当然是一个错误;如果您的编译器接受这个错误,那么它就坏了。我假设您的意思是,如果用另一个声明替换一个声明,仍然不会出现错误。数组访问没有范围检查.在编译时,通常不知道数组的大小,而且即使是这样,语言也不需要检查。在运行时,检查会降低性能,这将违背C+不为不需要的东西付费的理念。因此,数组结束后的访问会给出未定义的行为,这要由程序员来确保它不会发生。有时,无效的访问会导致分段错误,但这是不能保证的。通常,内存保护只应用于整个内存页,典型的页面大小为几千字节。有效内存页中的任何访问都不会被捕获。您访问的内存很有可能包含一些其他程序变量,或者调用堆栈的一部分,因此在其中写入内容可能会以您所能想象的任何方式影响程序的行为。如果你想安全,你可以std::vector,并且只使用它的at()功能。这将检查索引,如果异常超出范围,则抛出异常。它还将为您管理内存分配,修复示例中的内存泄漏。
打开App,查看更多内容
随时随地看视频慕课网APP