如何在C语言中释放未使用的内存分配?

3
例如,如果我在C字符串上分配了比所需更多的内存空间,是否有一种方法可以返回未使用的内存?或者这是自动完成的吗?
char *x = malloc(256);
strcpy(x, "Hello World");
// return back unused x memory allocation

5
@Arvnid!!! 这在 [tag:c] 中不存在。如果你在 c++ 中这样做,会导致未定义的行为,因为 delete 是在使用 new 分配内存时使用的。在这种情况下应该是 x = new[256]; 然后使用 delete[] x; 而不是 delete x; - Iharob Al Asimi
BWT:char *x = strdup("Hello World"); 或者至少 char *x = malloc(12); if (x != NULL) strcpy(x, "Hello World"); - Iharob Al Asimi
如果您知道您只需要使用12个字节,那么为什么不使用malloc(12)而不是256呢? - Pablo
补充@Pablo的评论,当你不知道在运行时需要分配多少内存时,应该精确使用malloc()。因此,当你知道时,你应该现在确切地知道需要多少。 - Iharob Al Asimi
@IharobAlAsimi 如果在编译时不知道内存空间怎么办?例如,在处理未知字符串大小的用户输入或读取文件的程序中。 - lostAtSeaJoshua
@lostAtSeaJoshua 用户输入应该受到一定大小的限制。例如:对于名称,限制为1024个字符。不受限制的用户输入会带来安全风险。 - chux - Reinstate Monica
2个回答

7
你可以调用realloc改变分配的大小; 这可以用于使其更大或更小。
计算机没有自动减少你的分配的依据。

在实际应用中,将字符串重新分配到字符串长度+1的长度是否安全? 例如:`char *x;` `x = malloc(256);` `strcpy(x, "Hello");` `x = realloc(x, (strlen(x) + 1));` - lostAtSeaJoshua
1
只要你不尝试访问已被释放的部分,那就可以。 - Scott Hunter
1
@lostAtSeaJoshua x = realloc(x, (strlen(x) + 1)); 在理论上,甚至可以无法重新分配到小一些的内存 - 因此请检查返回值。 这只取决于您希望让代码变得多么有弹性。 - chux - Reinstate Monica
@chux 是的,我在realloc返回null时添加了错误处理。 - lostAtSeaJoshua

2

这并不是自动完成的。这就是手动内存管理的好处和坏处。

您需要显式调用free(x);来释放内存返回给操作系统。而且要跟踪您的malloc()/free()对是一件很麻烦的事情,但它会产生回报,因为您可以对程序使用的内存进行精细控制。

如果您想分配恰好的内存量,则应该这样做。通常,当您调用malloc()时,您在编译时不知道分配大小,因此通常会分配确切的内存量。

如果您想要一个增长/缩小的内存缓冲区,则应考虑到malloc()是一个昂贵的调用。因此,您通常会分配足够的内存 - 一个很好的估计量 - 然后在您知道它不会再增长时将其缩小,或者如果您估计过少则将其扩大。


什么是好的部分? - Scott Hunter
@ScottHunter 你可以对程序的内存分配进行精细控制。如果你小心谨慎,并使用正确的工具,你将能够编写高效且没有任何错误的内存代码。 - Iharob Al Asimi
我认为这更加“有用”而不是“好看”,但你的看法可能不同。 - Scott Hunter
2
@IharobAlAsimi 在寻找 YMMV 时,您的结果可能会有所不同。 - chux - Reinstate Monica
@IharobAlAsimi 初学者在这里。你怎么知道 malloc() 是一个昂贵的调用?有没有一个包含这些信息的列表?或者你是通过编写一个测试程序来测试它需要多长时间的? - user56202
@user56202 请看一下这个 https://dev59.com/lWAg5IYBdhLWcg3wBXAR#24057744。你也可以在谷歌上搜索相关内容。关于这个问题,会有很多帖子。当然,当我说“昂贵”时,并不是指它会使程序变慢或者暗示什么。但是如果你需要频繁地增加某个缓冲区,请一次性增加大块内存,这样你就不需要一直调用 malloc()。这是一个非常常用的策略。 - Iharob Al Asimi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接