基本的Malloc/Free

3
如果我的程序代码片段如下所示:
struct Node *node;
while(...){
    node = malloc(100);
    //do stuff with node
}

这意味着每次循环while循环时,我都会重新分配100个字节,并由节点指针指向对应内存地址,是吗?
如果是这样的话,那么如果我只有一个指向最后一次malloc的指针,我该如何释放使用所有循环创建的内存?
谢谢!

3
简而言之,你不能这样做。有一个"每个malloc都必须与一个free配对"的经验法则是有原因的。 - user395760
5个回答

4
请确保分配恰好所需的大小:malloc(sizeof *node);——如果您转移到一个64位平台,所有成员的大小都会翻倍,您旧的96字节结构在新环境中可能需要192字节。
如果您没有指向任何已创建的struct Node的指针,则我认为您不应该首先使用malloc(3)来分配它们。如果您的应用程序需要数据在当前函数的调用范围之外持久存在,则malloc(3)最好。我期望您可以像这样重新编写您的函数:
struct Node node;
while(...){
    //do stuff with node
}

或者

while(...){
    struct Node node;
    //do stuff with node
}

根据您是否需要访问最后一个节点(第一个版本)或不需要访问(第二个版本),代码的处理方式会有所不同。

当然,如果您在这段代码之外确实需要使用这些结构体,则需要将它们的引用存储在某个地方。最好将它们添加到全局列表中以跟踪struct Node对象,或将每一个添加到上一个struct Nodenext指针中,或将每个添加到相应的struct User中并引用它们,具体取决于您的应用程序。


3
更好的写法是:node = malloc(sizeof *node);。需要澄清的是,在malloc(3)中,数字3指的是Unix手册的第3部分,而不是你要分配3个字节。 - Keith Thompson

1

如果您在一次迭代结束后不再需要malloc分配的空间,应立即释放它。

为了跟踪已分配的节点,您可以将它们保存在动态增长的列表中:

#include <stdlib.h>

int main() {
    int i;
    void *node;
    int prt_len = 0;
    void **ptrs = NULL;
    for (i = 0; i < 10; i++) {
        node = malloc(100);
        ptrs = realloc(ptrs, sizeof(void*) * ++prt_len);
        ptrs[prt_len-1] = node;
        /* code */
    }
    for (i = 0; i < prt_len; i++) {
        free(ptrs[i]);
    }
    free(ptrs);
    return 0;
}

注意:如果您需要使用这样的方法,那么您可能应该重新考虑您的算法!
否则请参见sarnold的答案

1
如果在循环之前将node = NULL设置为NULL,然后在node = malloc(100)之前使用free(node),那么你应该没问题。在循环退出后,您还需要执行free(node)。但是,这完全取决于“//do stuff with node”实际上做了什么。正如其他人指出的那样,malloc(100)不是一个好主意。我会使用malloc(sizeof(*node))。这样,如果node的类型更改,您就不必更改malloc行。

这在单一架构之外是不安全的,其中sizeof(struct Node)恰好为100字节。你绝不能像那样malloc一个结构体,而应该使用malloc(sizeof(struct Node)) - Brian Roach
@BrianRoach - 我只是在回答他的问题,而不是在评价他的技术。事实上,我更喜欢使用malloc(sizeof(*node))。 - Jim Rhodes
@BrianRoach,最好使用malloc(sizeof(*node))) - Kijewski

0
那么如果我只剩下一个指向最后一次malloc的指针,如何释放我用所有循环创建的所有内存?
你不能。你刚刚创建了一个巨大的内存泄漏
您必须跟踪每个malloc()的内存块,并在使用完毕后free()它。

0
你不能这样做。你需要将所有的指针存储起来以释放内存。只有在某个地方保存了这些指针,你才能释放内存。

你有没有看其他的回答?请写“you”,而不是“u”。实际上,这适用于生活的方方面面:如果你没有足够的时间再敲两个字母,就不要写任何东西。无论你说什么,写“u”和“r”都会让你听起来很愚蠢。 - Kijewski
1
@kay 没有任何不好的感觉,但是使用“u”或“你”对我来说没有关系。对于伟大的智慧来说也应该如此,因为科学已经证明大脑永远不会完全读取拼写 :) - Mohammed Khalid Kherani

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