为什么不让我得到一个运行时错误,当我访问数组的边界外的元素? [英] Why don't I get a runtime error when I access an out-of bounds element of an array?

查看:141
本文介绍了为什么不让我得到一个运行时错误,当我访问数组的边界外的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此code下面我试图访问一个数组的'-1'th元素,我没有得到任何运行时错误。

In this code below I try to access the '-1'th element of an array, I don't get any runtime error.

#include <stdio.h>

int A[10] = {0};

int main(){

    A[-1] += 12;

    printf("%d",A[-1]);

    return 0;
}

当我运行code,它输出 12 这意味着它是增加12到不存在A [-1]。直到今天,每当我曾试图访问超出边界的元素,我已经得到了一个运行时错误。我以前从来没有尝试过一个简单的code。

When I run the code, it outputs 12 that means it is adding 12 to the non-existent A[-1]. Till today whenever I had tried to access an out-of-bounds element, I had got a runtime-error. I had never tried it on a simple code before.

任何人都可以解释为什么成功呢我的code运行?

Can anyone explain why does my code run successfully?

我跑了我的电脑上,也对 ideone ,在这两种情况下成功运行。

I ran it on my computer and also on ideone, in both the cases it ran successfully.

推荐答案

您看到的,当你分配一个变量就是这样,它的土地堆栈。堆栈持有大约在每次调用函数的局部变量的信息小包装,说它简单的话。运行时能够检查,您是否超出分配的堆栈的界限,但如果你在栈上的无效的地方写一些数据。堆栈可能看起来像下面这样:

You see, when you allocate a variable like this, it lands on the stack. Stack holds small packages of information about local variables in each function you call, to say it in simple words. The runtime is able to check, whether you exceed the bounds of allocated stack, but not if you write some data in the invalid place on the stack. The stack may look like the following:

[4个字节 - 一些PTR] [4个字节 - A的第一个元素] [4个字节 - A的第二个要素] ...

[4 bytes - some ptr][4 bytes - A's first element][4 bytes - A's second element] ...

当你试图给-1th数组元素,你竟然试图读取四个字节preceding数组(四个字节,因为它是一个int数组)。您覆盖堆栈举行一些数据 - 但是这仍然是有效的进程的内存,所以没有从系统的投诉

When you try to assign to -1th element of an array, you actually attempt to read four bytes preceding the array (four bytes, because it's an int array). You overwrite some data held on stack - but that's still in valid process's memory, so there are no complaints from the system.

尝试运行在发布模式下此code在Visual Studio:

Try running this code in release mode in Visual Studio:

#include <stdio.h>

int main(int argc, char * argv[])
{
    // NEVER DO IT ON PURPOSE!
    int i = 0;
    int A[5];

    A[-1] = 42;
    printf("%d\n", i);

    getchar();
    return 0;
}


编辑:的回应意见

我错过了一个事实,即A是全球性的。它不会在堆栈中举行,而是(主要是可能)二进制模块。数据段,但解释的休息站:A [-1]仍然是进程的内存中,这样的分配不会提高AV。然而,这样的分配将覆盖东西,那就是前(可能是一个指针或二进制模块的其它部分)导致未定义的行为。

I missed the fact, that A is global. It won't be held in stack, but instead (mostly probably) in .data segment of the binary module, however the rest of explanation stands: A[-1] is still within process's memory, so assignment won't raise AV. However, such assignment will overwrite something, that is before A (possibly a pointer or other part of the binary module) resulting in undefined behavior.

请注意,我的例子可以工作,可能不会,这取决于编译器(或编译器模式)。例如,在调试模式下运行程序返回0 - 我想,那内存管理器插入堆栈帧之间的一些岗哨数据捕获错误如缓冲区溢出/欠载

Note, that my example may work and may not, depending on compiler (or compiler mode). For example, in debug mode the program returns 0 - I guess, that memory manager inserts some sentry data between stack frames to catch errors like buffer over/underrun.

这篇关于为什么不让我得到一个运行时错误,当我访问数组的边界外的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆