【问题标题】:heap corruption when free() struct pointer after memcpymemcpy 后 free() 结构指针时堆损坏
【发布时间】:2021-12-14 23:08:03
【问题描述】:

我正在使用 Visual Studio 2019 用 C 语言编写一个通用排序函数。

我用原型做了一个通用的插入排序函数:

void insertion_sort(void* const arr, size_t left, size_t right, size_t width, _Cmpfun cmp)

_Cmpfunc 是 typedef as

typedef int (*_Cmpfun) (const void*, const void*);

为了测试这个函数的工作情况,我为这样的测试制作了一个结构 ELEMENT。

typedef struct {
    unsigned int score;
    float data[3];
    char comments[16];
} ELEMENT;

为了保存数据,我这样动态分配内存。

    char* top_ptr = (char*)malloc(sizeof(width));

每当我尝试free() top_ptr 之后

memcpy(top_ptr, some_valid_pointer, width)

其中 some_valid_pointer 不是 NULL 指针,width 是 insert_sort 的参数

,Visual Studio 弹出堆损坏错误。

这仅在调用memcpy 函数后发生。

如果我这样做:

char* top_ptr = (char*)malloc(sizeof(width));
free(top_ptr);

效果很好。

我在网上搜索了什么是堆损坏错误,发现当memcpy函数覆盖结构变量的无效内存时发生。

我在main 中使用width = sizeof(ELEMENT) 调用函数insertion_sort,因此考虑了结构变量的填充。

我不知道是什么问题。我的代码有什么问题?

【问题讨论】:

  • 我们不能说没有看到实际的代码。请提供一个minimal reproducible example 来说明问题。另请注意,C 和 C++ 是不同的语言,请选择一种。
  • size_t widtharr 的单个元素的字节数。例如arr[0] 的下一个元素的指针将是arr + width。底层结构怎么会大于宽度? (函数调用width = sizeof(ELEMENT)

标签: c++ c memcpy heap-corruption


【解决方案1】:
width = sizeof(ELEMENT)

sizeof(ELEMENT),使用粗略计算,应该在大约 30 字节附近。这就是你的ELEMENT 的大小。

char* top_ptr = (char*)malloc(sizeof(width));

由于widthsize_tsizeof(size_t) 将是 4 或 8,具体取决于您是在编译 32 位还是 64 位代码。

因此,这将分配 4 或 8 个字节。 memcpyed 远远少于 30 个字节。

这是你的堆损坏,就在这里。

【讨论】:

  • 哦,我应该打电话给malloc(width)。非常感谢!!
【解决方案2】:

你正在分配大小为sizeof(width)的内存:

char* top_ptr = (char*)malloc(sizeof(width));

但是复制大小为width的内存:

memcpy(top_ptr, some_valid_pointer, width)

很可能是sizeof(width) < width,因此是堆损坏。

【讨论】:

  • 非常感谢!我犯了一个愚蠢的错误......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-06
  • 1970-01-01
  • 1970-01-01
  • 2020-08-02
相关资源
最近更新 更多