在此代码中释放内存的正确方法是什么?
#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;
}
由于两个指针指向同一个方向
答案 0 :(得分:16)
我认为你的困惑来自(无灵感)表达式&#34;自由指针&#34; (你在帖子中使用过,但自从编辑后)。你没有自由指针。你免费记忆。指针只是告诉哪个内存。
在你的例子中,你有:从malloc
获得的记忆。 string1
指向这个记忆。然后,当您调用realloc
时,会获得一个新的内存块(可能从相同的地址开始,可能不是),但realloc
会在需要时注意释放旧的内存块(因此是未定义的访问行为)或自己释放)。 string2
指向这个新的内存块。
所以你必须free
只从realloc
获得的内存块。 string2
指向那段记忆。
答案 1 :(得分:7)
简而言之,没有。
7.22.3.5
realloc
功能...
realloc
函数释放指向的旧对象 通过ptr
并返回指向具有该对象的新对象的指针 由size
指定的大小。新对象的内容应为 与解除分配之前的旧对象相同,直到 较小的新旧尺寸。超出新对象中的任何字节 旧对象的大小具有不确定的值。
致电realloc()
后,您无需free()
指针通过传递到 realloc()
所占用的内存 - 您必须free()
指针realloc()
寻址的内存返回。 (除非realloc()
返回NULL
,在这种情况下,原始内存块 - 将传递给 realloc()
- 必须为{{ 1}}&#39; d)
答案 2 :(得分:3)
当您调用realloc
时,返回的指针与原始指针相同,或者返回新指针并且原始指针变为无效。在第一种情况下,在free
和string1
上调用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
“就地”调整了内存块的大小,这意味着string2
和string1
的值相等。在这种情况下,调用free(string1)
是错误的,因为你释放了两次相同的指针。
可能是realloc
在调整大小的过程中将您的数据移动到新位置。在这种情况下,string2
和string1
的值不相等。但在这种情况下,在找到数据的新位置并将其复制到那里之后, 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;
}
如果你有魔术函数可以计算指针的分配大小,你可以像这样自己实现realloc
。 malloc
几乎必须在内部使用此功能才能使free
正常工作。
realloc
也可以做一些聪明的事情,例如确定你重新分配到较小的尺寸并且只是免费分配一部分,或者发现你正在增加你的分配并且那里有&#39}适合它后足够的空间。但是你不需要考虑这些案件。认为realloc
是malloc + memcpy + free不会误导你,除非你需要记住realloc
失败并返回NULL意味着它没有做free
。
答案 5 :(得分:0)
realloc implicity释放输入,它可能根本不做任何事情,但你不能在重新分配内存后释放它。所以
background_mouseOver