动态分配数组的有趣行为

Interesting behavior with dynamically allocated array

本文关键字:数组 动态分配      更新时间:2023-10-16

所以我使用的是一个动态分配的数组,我已经将它设置为包含5个元素,因此应该是0-4。我制作了一个函数来在必要时保留它,但我想看看当我在[5]处为数组赋值时,我是否会出现预期的程序崩溃。但是,没有错误,直到[6]。

这是我的代码:

int* dynamic_arr;
dynamic_arr = new int[5];
for(int i = 0; i <= 100; i++){
    dynamic_arr[i] = i;
    used++;
    cout << dynamic_arr[i]<<endl;
}

这是输出:

0 //i[0]
1 //i[1]
2 //i[2]
3 //i[3]
4 //i[4]
5 //i[5]  <-- should be out of range

之后它就崩溃了。

为什么我能够为数组中由于缺少更好的项而超出范围的部分指定值?

感谢

OpSrcFTW

编辑:感谢你们的回答,谢谢。对不起,我会在下次发帖之前阅读更多内容以获得快速回复。

在数组末尾之外进行访问会产生未定义的行为。它不一定会产生崩溃。任何事情都有可能发生。

访问数组超出其边界是未定义的行为。任何事情都可能发生,不需要重复,尝试"理解"你认为可能存在的任何模式都没有意义。

访问超出数组大小将产生未定义的行为。未定义的行为包括代码崩溃、正常工作、在一台计算机上工作而不是在另一台计算机,重新启动计算机或摧毁整个宇宙。

正如其他人已经指出的,您有未定义的行为,因此虽然可能发生崩溃,但代码也可以正常工作。

在像您这样的情况下,当您访问时稍微超过您分配的内存末尾时,似乎可以工作是很常见的。为免费存储管理内存的代码通常会将您的请求大小四舍五入到它认为方便的下一个大小,例如2的幂。因此,在您请求的内容结束后至少有一点内存可以写入,而不会出现可见的问题,这并不罕见。

当然,你不能指望这一点——即使是使用相同标志的同一编译器也不行,等等。例如,标准库可以根据目标机器上的可用内存量来决定如何操作,在有足够RAM可用时使用更多填充来优化速度,在可用内存较少时使用更少填充来减少内存使用。

因此,不,你不能依赖于任何特定点的崩溃——但这也不是一个你可以通过测试或认为这是你只需要担心的事情,如果你要移植代码的话。