【问题标题】:"pointer being freed was not allocated" while using memcpy使用 memcpy 时“未分配被释放的指针”
【发布时间】:2017-03-07 16:43:00
【问题描述】:

我尝试使用 memcpy 将内容从一个数组复制到另一个数组,代码如下:

#include <stdio.h>

int main(){
    int *a;
    a = (int*) malloc(sizeof(int) * 4);
    a[0] = 4;
    a[1] = 3;
    a[2] = 2;
    a[3] = 1;

    int *b;
    b = (int*) malloc(sizeof(int) * 4);
    memcpy(&b, &a, sizeof(a));

    free(a);
    for (int i = 0; i < 4; i++){
        printf("b[%d]:%d",i,b[i]);
    }
    printf("%d\n",sizeof(b));
    free(b);

    return 0;
}

但是,当我尝试运行它时,遇到以下错误:

b[0]:4b[1]:3b[2]:2b[3]:18
mem(6131,0x7fffbb4723c0) malloc: *** error for object 0x7fa5a4c02890: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

如果我删除free(b) 这段代码,这个错误就会消失,但是,我不知道为什么,因为我明确地为它分配了资源。

【问题讨论】:

标签: c pointers malloc


【解决方案1】:

您的memcpy 错误。您将指针a 的值复制到b,而不是将a 指向的数据复制到b 指向的缓冲区中。因为ab 指向同一个地方,所以你最终会执行双重释放。将您的 memcpy 电话替换为:

memcpy(b, a, sizeof(int)*4);

【讨论】:

  • @JeremyP 这被认为落后(目前已删除)cmets。
【解决方案2】:
memcpy(&b, &a, sizeof(a));

这不会将a 指向的4 个整数复制到b 指向的4 个整数。

这会用a 的内容覆盖b。然后你最终做了一个双重释放,因为ab 包含相同的地址。

我将重复我对您的问题的评论:您需要花时间了解指针和指针之间的区别。什么持有和地址,以及该地址的内容。

【讨论】:

  • 我认为memcpy 没有任何内存垃圾。 sizeof(a)int* 的大小。
  • @Kevin - 现在我有时间重新思考我写的废话,我能说的就是感谢您指出这一点。我想我应该遵循我自己对 OP 的建议 :)
【解决方案3】:

这就是我们说 not to cast the return value of malloc() and family in C.的确切问题。

首先,您缺少stdlib.h 包含,因此,malloc() 的原型是未知的,并且您的编译器假设它返回一个int。这会在隐式声明和实际定义之间造成不匹配,后者会在稍后阶段调用undefined behavior

也就是说,另一个主要问题是当你写memcpy(&amp;b, &amp;a, sizeof(a)); 时这是非常错误的。您想自己提供ab,因为您想将a 指向的内存位置的内容复制到b 指向的内存位置,而不是指针的地址。

在您的情况下,错误调用实际上弄乱了b 的内容,即malloc() 返回的实际指针。因此,正如我们所知,将未完全由内存分配器函数返回或已经 free()-d 的指针传递给 free() 会导致 UB,引用 C11,第 7.22.3.3 章,

[...] 否则,如果 该参数与内存管理先前返回的指针不匹配 函数,或者如果空间已通过调用 freerealloc 释放,则 行为未定义。

你遇到了麻烦,因为b 持有的当前指针与a 相同,后者已经传递给free()。正如其他答案中提到的那样[1][2],你需要写

 memcpy(b, a, sizeof(int)*4);

故事的寓意:启用编译器警告并始终检查数据类型。

【讨论】:

    【解决方案4】:

    也许是因为你释放 b 时释放了 (a)。因为做memcpy后内存区是一样的。最后尝试做free(b),没有free(a)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-25
      • 2018-09-30
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多