realloc后的空闲内存如何

时间:2016-05-03 19:55:29

标签: c

在此代码中释放内存的正确方法是什么?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main( void ){

    char *string1, *string2;
    string1 = (char*) malloc(16);

    strcpy(string1, "0123456789AB");

    string2 = realloc(string1, 8);

    printf("string1 Valor: %p [%s]\n", string1, string1);
    printf("string2 Valor: %p [%s]\n", string2, string2);

    free(string1);
    free(string2);
    return 0;
}

由于两个指针指向同一个方向

6 个答案:

答案 0 :(得分:16)

我认为你的困惑来自(无灵感)表达式&#34;自由指针&#34; (你在帖子中使用过,但自从编辑后)。你没有自由指针。你免费记忆。指针只是告诉哪个内存。

在你的例子中,你有:从malloc获得的记忆。 string1指向这个记忆。然后,当您调用realloc时,会获得一个新的内存块(可能从相同的地址开始,可能不是),但realloc会在需要时注意释放旧的内存块(因此是未定义的访问行为)或自己释放)。 string2指向这个新的内存块。

所以你必须free只从realloc获得的内存块。 string2指向那段记忆。

答案 1 :(得分:7)

简而言之,没有。

the C Standard

  

7.22.3.5 realloc功能

     

...

     

realloc函数释放指向的旧对象   通过ptr并返回指向具有该对象的新对象的指针   由size指定的大小。新对象的内容应为   与解除分配之前的旧对象相同,直到   较小的新旧尺寸。超出新对象中的任何字节   旧对象的大小具有不确定的值。

致电realloc()后,您无需free()指针通过传递到 realloc()所占用的内存 - 您必须free()指针realloc()寻址的内存返回。 (除非realloc()返回NULL,在这种情况下,原始内存块 - 将传递给 realloc() - 必须为{{ 1}}&#39; d)

答案 2 :(得分:3)

当您调用realloc时,返回的指针与原始指针相同,或者返回新指针并且原始指针变为无效。在第一种情况下,在freestring1上调用string2会导致双重释放,因为指针相等。在第二种情况下,在free上调用string1是免费的,因为它已经被释放了。

因此,无论哪种方式,你都有双倍免费,这会产生undefined behavior

来自realloc的手册页:

void *realloc(void *ptr, size_t size);
     

realloc()函数将ptr指向的内存块的大小更改为size字节。内容将在该范围内保持不变   从该地区的起点到最新的新旧   大小。如果新大小大于旧大小,则添加内存   不会被初始化。如果ptr为NULL,则调用是等效的   对于malloc(size),对于所有大小的值;如果size等于零,和   ptr不是NULL,那么调用相当于free(ptr)。除非ptr   为NULL,它必须由之前调用malloc()返回,   calloc()或realloc()。 如果指向的区域被移动,则免费(ptr)   完成了。

     

realloc()函数返回指向新分配的指针   记忆,适用于任何类型的变量并且可能是   与ptr 不同,如果请求失败,则为NULL。

同样来自free的手册页:

  

free()函数释放ptr指向的内存空间   必须由之前调用malloc(),calloc()或   realloc的()。否则,或者如果之前已经调用了free(ptr),   发生未定义的行为。如果ptr为NULL,则不执行任何操作。

您只需要free(string2)

答案 3 :(得分:1)

简短回答:在您的代码中,调用free(string2)是正确的,并且足够了。调用free(string1)不正确。

当您调用realloc(并假设调用成功)时,其返回值(存储在string2中)成为引用您的一块内存的唯一方法有

可能realloc“就地”调整了内存块的大小,这意味着string2string1的值相等。在这种情况下,调用free(string1)是错误的,因为你释放了两次相同的指针。

可能是realloc在调整大小的过程中将您的数据移动到新位置。在这种情况下,string2string1的值不相等。但在这种情况下,在找到数据的新位置并将其复制到那里之后, realloc会自动为您释放旧块。因此,再次调用free(string1)是错误的,因为你释放了一个已经释放的指针。

答案 4 :(得分:1)

realloc视为等同于:

void *
realloc(void *old, size_t new_size)
{
    size_t old_size = magic_internal_function_that_knows_the_size_of(old);
    void *new = malloc(new_size);
    if (new == NULL)
        return NULL;
    memcpy(new, old, new_size > old_size ? old_size : new_size);
    free(old);
    return new;
}

如果你有魔术函数可以计算指针的分配大小,你可以像这样自己实现reallocmalloc几乎必须在内部使用此功能才能使free正常工作。

realloc也可以做一些聪明的事情,例如确定你重新分配到较小的尺寸并且只是免费分配一部分,或者发现你正在增加你的分配并且那里有&#39}适合它后足够的空间。但是你不需要考虑这些案件。认为realloc是malloc + memcpy + free不会误导你,除非你需要记住realloc失败并返回NULL意味着它没有做free

答案 5 :(得分:0)

realloc implicity释放输入,它可能根本不做任何事情,但你不能在重新分配内存后释放它。所以

background_mouseOver