在此代码中释放内存的正确方法是什么?
#include #include #include 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; }
由于两个指针指向同一个方向
我认为你的困惑来自(无灵感)表达式“自由指针”(你在post中使用过,但自从编辑后)。 你没有自由指针 。 你释放记忆 。 指针只是告诉哪个内存。
在你的例子中,你有:从malloc
获得的malloc
。 string1
指向此内存。 然后当你调用realloc
时,会获得一个新的内存块(可能从相同的地址开始,可能不是),但是realloc
会在需要时注意释放旧的内存块(因此是未定义的访问行为或自己释放它)。 string2
指向这个新的内存块。
所以你必须free
从realloc
获得的内存块。 string2
指向那个内存。
总之,没有。
根据C标准 :
7.22.3.5
realloc
function…
realloc
函数解除分配ptr
指向的旧对象,并返回指向具有size指定size
的新对象的指针 。 新对象的内容应与解除分配之前的旧对象的内容相同,直到新旧大小中的较小者为止。 新对象中超出旧对象大小的任何字节都具有不确定的值。
一旦调用realloc()
,就不必free()
传递给 realloc()
的指针寻址的内存 – 你必须free()
由指针realloc()
返回的内存。 (除非realloc()
返回NULL
,在这种情况下, 原始的内存块 – 传递给 realloc()
– 必须是free()
‘d。)
当您调用realloc
,返回的指针与原始指针相同,或者返回一个新指针并且原始指针变为无效。 在第一种情况下,在string1
和string2
上调用free
导致双重释放,因为指针是相等的。 在第二种情况下,在string1
上调用free
是双重释放的,因为它已经被释放了。
所以无论哪种方式,你都有一个双重自由,导致未定义的行为 。
从realloc的手册页:
void *realloc(void *ptr, size_t size);
realloc()函数将ptr指向的内存块的大小更改为size字节。 内容将在从区域的开始到新旧尺寸的最小范围内保持不变。 如果新大小大于旧大小,则不会初始化添加的内存。 如果ptr为NULL,则对于所有size值,调用等效于malloc(size); 如果size等于零,并且ptr不为NULL,则调用等效于free(ptr)。 除非ptr为NULL,否则必须由之前调用malloc(),calloc()或realloc()返回。 如果指向的区域被移动,则完成自由(ptr)。
realloc()函数返回一个指向新分配的内存的指针,该内存适用于任何类型的变量,可能与ptr不同 ,如果请求失败,则返回NULL。
也可以从手册页免费获取 :
free()函数释放ptr指向的内存空间,该内存空间必须由之前调用malloc(),calloc()或realloc()返回。 否则,或者如果之前已经调用了free(ptr),则会发生未定义的行为 。 如果ptr为NULL,则不执行任何操作。
你只需要free(string2)
。
简短的回答:在你的代码中,调用free(string2)
是正确的,并且足够了。 调用free(string1)
不正确。
当你调用realloc
(并假设调用成功)时,它的返回值(存储在string2
)成为引用你拥有的一块内存的唯一方法。
可能是realloc
“就地”调整了内存块的大小,这意味着string2
和string1
的值相等。 在这种情况下,调用free(string1)
是错误的,因为你释放了两次相同的指针。
可能是realloc
在resize的过程中将数据移动到新位置。 在这种情况下, string2
和string1
的值不相等。 但在这种情况下,在找到数据的新位置并将其复制到那里后, realloc
自动为您释放旧块 。 所以,再次调用free(string1)
是错误的,因为你释放了一个已经释放的指针。
将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
使用此function。
realloc
也可以做一些聪明的事情,比如找出你正在重新分配到一个较小的大小,只是释放你的部分分配,或者发现你正在增加你的分配,并且在适应它之后有足够的空间。 但是你不需要考虑这些情况。 认为realloc
是malloc + memcpy + free不会误导你,除非你需要记住realloc
失败并返回NULL意味着它没有free
。
realloc implicity释放输入,它可能根本不做任何事情,但你不能在重新分配内存后释放它。 所以
char *string1, *string2; string1 = (char*) malloc(16); .... string2 = realloc(string1, 8); // this line implicitly frees string1 free(string1); // this is wrong !!! free(string2);
以上就是c/c++开发分享realloc后的空闲内存如何相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/560208.html