我正在使用 VS08 构建/运行以下 C++ 代码:
#include <stdlib.h>
struct Header
{
int count;
}*lstHeader=NULL;
int main()
{
for(int i=0;i<10;i++)
{
lstHeader=(Header*)realloc(lstHeader,sizeof(Header)+i);
lstHeader[i].count=i;
}
return 1;
}
运行后我得到以下 VS 异常:
Windows has triggered a breakpoint in MyProgram.exe.
This may be due to a corruption of the heap, which indicates a bug in
MyProgram.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while MyProgram.exe has focus.
The output window may have more diagnostic information.
我已经尝试 malloc lstHeader 而不是将其分配给 NULL,但是发生了相同的 VS 异常,我无法理解。
最佳答案
您需要考虑当 i
达到 1 时会发生什么。让我们假设一个四字节整数。
在 i == 0
处,您为一个 Header
分配了足够的字节加上一个额外的零字节。然后将 Header[0].count
设置为 0。没有问题,您只更改了分配的四个字节。
在 i == 1
处,您为一个 Header
加上一个额外的字节(总共五个字节)分配了足够的字节。然后将 Header[1].count
设置为 1。这会更改内存块的字节 4、5、6 和 7(从零开始),尽管事实上您只有字节 0 到 4 可用于你。换句话说,该操作需要额外的 4 个字节,而不是您要求的 1 个额外字节。
从图形上看:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | |1|1|1|1|1|1|1|1|1|1|2|2|2|2|
offset: |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
i=0, get: <------->
use: <------->
i=1, get: <--------->
use: <--------------->
i=2, get: <----------->
use: <----------------------->
i=3, get: <------------->
use: <------------------------------->
i=4, get: <--------------->
use: <--------------------------------------->
i=5, get: <----------------->
use: <----------------------------------------------->
如您所见,每次迭代都会给您一个额外的字节,但您需要额外的四个字节。现在这实际上可能会工作一段时间,因为大多数 malloc
调用都会给你一个最小分辨率,比如 16 字节(要求 1、2、3 或 16,你得到 16,要求 20 或 30,你得到 32)。但它仍然是未定义的行为,您不应该依赖它。
而且,无论如何,您最终都会到达不再有帮助的地步。该点是您需要的 sizeof*(i+1)
超过 16 字节阈值而您请求的 sizeof+i
保持在该阈值以下的位置。然后,您将写入超出分配的内存(即使有填充),并且您将占用内存空间。
你可能应该拥有的是:
lstHeader = realloc (lstHeader, sizeof(Header) * (i+1));
这将确保您在内存分配中有足够的空间用于所需的 Header
元素。它是 i+1
的原因是因为即使 i
为零,初始分配也必须有一个元素。
关于c++ - realloc 分配失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5336405/