c++ - realloc 分配失败

标签 c++ c

我正在使用 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/

相关文章:

c++ - CMake find_package 与 GLEW

c++ - C++ 中字符串和 wstring 的控制台打印

c - 作为另一个函数的参数的 typedef 函数

c - 如何在简单的游戏(Windows库)中使一些角色自动移动而无需sleep()

c - 在C中实现Linkedlist时,head没有被设置为NULL

c - 在 GCC 中编译时在 C 中编辑操作的 ASM 结果

java - 在jsp中包含一个cpp文件

c++ - 可以编写一个接受类型并返回不同类型的函数吗

c++ - 映射/设置迭代器在 C++ 中不可递增错误

c++ - 为什么程序员有时引用 "C++/STL"就像它是一种单独的语言一样?