我们可以使用realloc释放动态分配内存吗?

时间:2016-09-03 10:42:42

标签: c heap-memory

我的朋友和我讨论过释放动态分配的内存。他告诉我可以使用realloc()释放内存,我否认了这一点。 我们考虑以下代码:

int main()
{
    int *p = (int *)malloc(sizeof(int) * 10);
    int *q = (int *)malloc(sizeof(int) * 10);

    free(p);
    p = NULL;

    realloc(q, sizeof(int) * 0);
    q = NULL;

    _getch();
    return 0;
}

我们假设 p q 指向地址0x1000&分别为0x2000。 在上面的代码中, p q int指针,指向RAM中动态分配的40个字节的内存块。在执行free(p)时释放内存地址(0x1000)。释放的内存地址(0x1000)可以再次由OS使用。然后, NULL 被分配给指针变量p,以防止p成为悬空指针。

realloc(q, sizeof(int) * 0);

realloc()只是将 q 指向的内存块缩小为零。但 q 仍然指向同一地址(0x2000),并且该地址未被释放。在为指针 q 指定NULL值时, q 现在指向NULL并且 q 指向的地址(0x2000)是未释放,该地址(0x2000)的链接丢失。操作系统将来不能使用该地址(0x2000),直到程序结束。

我的理解是否正确?

2 个答案:

答案 0 :(得分:4)

realloc(q, sizeof(int) * 0);

相同
realloc(q, 0);

7.22.3.5中的C标准 - > 2 realloc函数表示:

  

..并返回指向具有指定大小的新对象的指针   尺寸。新对象的内容应与该对象的内容相同   在解除分配之前的旧对象,直到新旧的较小者   尺寸。

但它没有明确说明如果新大小为零会发生什么。 但是你仍然有一个artist指针,可以传递给free

考虑

char *a;
a=malloc(2*sizeof *a);
a=realloc(a,0);
// Note I'm purposely NOT using a temporary variable to store 'realloc' results
// Moreover, above is BAD practice.
free(a); // Is this permitted? YES !! Did we technically free memory above? NO !!
//Compiler will not yell at you for the above, in fact it is legal as per the standard
return 0; // No output for this one

VS

char *a;
a=malloc(2*sizeof *a);
free(a);
//You're not suppose to free(a) again.
free(a); 
//Compiler will yell at you for the above.
return 0;

<强>输出

double free or corruption (fasttop): 0x0000000000915010

<强>结论

  • deallocationfreeing并不完全相同。
  • reallocfree都可以解除分配内存,但只有free可以释放内存。

那说

free(p);
p = NULL;

是释放内存的推荐方法。请检查[ this ]回答。

答案 1 :(得分:4)

realloc(, 0) implementation dependent and not equivalentfree()

那就是说,你可能很幸运:

#include <stdio.h>
#include <malloc.h>

int main() {
        char *a;
        a = malloc(1024);
        printf("a = %08lx\n", a);
        free(a);
        a = malloc(1024);
        printf("a = %08lx\n", a);
        realloc(a, 0);
        a = malloc(1024);
        printf("a = %08lx\n", a);
}

gcc version 6.1.1 20160815 [gcc-6-branch revision 239479] (SUSE Linux)
ldd --version

ldd (GNU libc) 2.23

a = 01dad010
a = 01dad010
a = 01dad010

所以第二个malloc,在realloc(,0)之后,&#34;看到&#34;以前的一个免费街区。我认为这意味着在这种情况下realloc重复了free的行为。 不要依赖