使用由malloc()分配的内存空间进行重复利用

3

我是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: 我担心会出现以下情况:在第一次迭代中,读取了5个字符,例如“abcde”;在第二次迭代中,只读取了3个字符(较短的行),例如“fgh”。我最终会得到“fghde”,这似乎很奇怪? - user3424826

A: 在C语言中,字符串以空字符结尾。是的,旧字符串的一部分仍然存在,但会有一个NUL字符标记新字符串的结尾。将来,如果您有特定的担忧(比如那个问题),请提前展示出来,以便可以直接解决问题,而不需要来回沟通。那只会浪费每个人的时间。 - Jonathon Reinhart

Q: 也许我应该这样重新表达我的问题:每次重用之前是否需要清除已分配的空间?(在重用之前清除每个字节)

A: 对这个问题的答案是:这取决于情况。如果你正在处理一个C字符串,那么不需要清除它(因为有空字符,正如我所提到的)。如果它是动态分配的(malloc'd)结构体,那么是的,你应该memset(p, 0, sizeof(*p)),或手动将每个成员设置为零。 - Jonathon Reinhart


你有什么理由认为你不能重复使用malloc提供的缓冲区吗?这是你的内存,你已经分配了它。你可以随意使用它,直到你释放它。 - Jonathon Reinhart
嗨。我对每次迭代后不清除分配的空间有些怀疑。更具体地说,我担心可能会发生以下情况:在第一次迭代中,读入了5个字符,比如"abcde";在第二次迭代中,只读入了3个字符(较短的行),比如"fgh"。最终会得到"fghde"这样奇怪的结果吗? - user3424826
我担心可能会出现以下情况:在第一次迭代中,读取了5个字符,例如"abcde";在第二次迭代中,只读取了3个字符(较短的行),例如"fgh"。最终结果会是"fghde",看起来有些奇怪吗? - user3424826
在C语言中,字符串是以空字符结尾的。所以是的,一些旧的字符串仍然存在,但是会有一个NUL字符来标记新字符串的结尾。将来如果你有特定的问题(比如这个),请提前提出,这样可以避免来回讨论,节省大家的时间。 - Jonathon Reinhart
很棒的答案,非常清晰明了。感谢你,我会注意问题的方式以后。 - user3424826
显示剩余2条评论
2个回答

3

没问题。在'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;
}

1
malloc和free的使用是正确的,但while(*s != NULL)在运行时可能不正确。以下做法可能更好。
while (!feof(fp)) {
    fgets(s,MAX_CHAR_IN_LINE,fp);
}

非常感谢这个很棒的提示。 - user3424826

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