重用 malloc() 分配的内存空间

Posted

技术标签:

【中文标题】重用 malloc() 分配的内存空间【英文标题】:Reusing memory space allocated by malloc() 【发布时间】:2014-03-16 04:19:56 【问题描述】:

我是 C 的新手,对 malloc() 的使用有几个问题: 可以重用分配的内存块吗?更具体地说,我正在尝试做的事情如下(尝试使用 fgets 解析文件):

#include <stdio.h>
#include <stdlib.h>
main() 
    /*... some code here to open a file and give pointer to fp */

    char *s=(char*) malloc(MAX_CHAR_IN_LINE);

    do 
        //QUESTION: is this right to reuse s in each iteration?
        fgets(s,MAX_CHAR_IN_LINE,fp);
     while (*s!=NULL);

    free(s);

谢谢!


感谢您的回答! 以下是相关后续Q/As的总结

问:我担心可能会发生以下情况:在第一次迭代中,读入了 5 个字符,比如“abcde”;在第 2 次迭代中,只读入了 3 个字符(较短的行),例如“fgh”。我最终会得到看起来很奇怪的“fghde”吗? – 用户 3424826

答:在 C 中,字符串以空值结尾。所以是的,一些旧字符串仍然存在,但会有一个 NUL 字符标记新字符串的结尾。将来,如果您有一个特定的问题(例如那个),请提前提出,这样就可以在没有所有来回的情况下解决它。只会浪费大家的时间。 ——乔纳森·莱因哈特

问:也许我应该把我的问题改写成这样:是否有必要在每次重用之前清除分配的空间? (在重用之前清除每个字节)

A:这个问题的答案是:视情况而定。如果它是您正在使用的 C 字符串,那么不,它是不必要的(因为空终止符,就像我提到的那样)。如果它是动态分配的(malloc'd)结构,那么是的,您应该 memset(p, 0, sizeof(*p)),或者手动将每个成员设置为零。 ——乔纳森·莱因哈特

【问题讨论】:

你有理由相信你不能重用malloc提供的缓冲区吗?这是你的内存,你已经分配了。你可以随意使用它,直到你free它。 嗨。我有点怀疑每次交互后不清除分配的空间。更具体地说,我担心可能会发生以下情况:在第一次迭代中,读入了 5 个字符,比如“abcde”;在第 2 次迭代中,只读入了 3 个字符(较短的行),例如“fgh”。我最终会得到看起来很奇怪的“fghde”吗? 为什么?这只是记忆。如果你写了一些东西,它会一直留在那里,直到你再次改变它(或释放它)。 我担心可能会发生以下情况:在第一次迭代中,读入了 5 个字符,比如“abcde”;在第 2 次迭代中,只读入了 3 个字符(较短的行),例如“fgh”。我最终会得到看起来很奇怪的“fghde”吗? 在 C 中,字符串是 null-terminated。所以是的,一些旧字符串仍然存在,但会有一个 NUL 字符标记新字符串的结尾。将来,如果您有一个特定的问题(例如那个问题),请提前提出,这样就可以在没有所有来回的情况下解决它。这只是浪费大家的时间。 【参考方案1】:

是的,没关系。在 'malloc' 和 'free' 之间,内存是你的,可以随心所欲。

我应该补充一点:如果 malloc 失败,它将返回 0(无效地址)。如果发生这种情况,您的示例将在第一次迭代时出现段错误。为了解决这个问题,您可以按如下方式修改您的程序:

#include <stdio.h>
#include <stdlib.h>
int main() 
    /*... some code here to open a file and give pointer to fp */

    char *s=(char*) malloc(MAX_CHAR_IN_LINE);
    if(s == NULL) 
        printf("Error: malloc failed.");
        return 1;
    

    do 
        //QUESTION: is this right to reuse s in each iteration?
        fgets(s,MAX_CHAR_IN_LINE,fp);
     while (*s!=NULL);

    free(s);
    return 0;

【讨论】:

【参考方案2】:

malloc 和 free 的使用是可以的,但是 while(*s != NULL) 运行时可能不正确。以下可能会更好。

while (!feof(fp)) 
    fgets(s,MAX_CHAR_IN_LINE,fp);

【讨论】:

很棒的小费感谢它。

以上是关于重用 malloc() 分配的内存空间的主要内容,如果未能解决你的问题,请参考以下文章

C语言 malloc()函数 分配内存空间尺寸的问题

C语言 malloc()函数 分配内存空间尺寸的问题

怎么查看动态分配内存空间的大小(c语言)。

内存空间

内存动态分配与释放

二动态内存分配与使用