malloc 和 free 如何处理错误?

Posted

技术标签:

【中文标题】malloc 和 free 如何处理错误?【英文标题】:How does malloc and free work with errors? 【发布时间】:2022-01-11 07:06:32 【问题描述】:

我刚刚在 C 中学习 malloc() 和 free() 并偶然发现了一个我在任何地方都找不到的重要问题。让我们以这个简单的代码 sn-p 为例:

    int main(int argc, char  *argv[])

    char *test = malloc(sizeof(char) * 30);
    strcpy(test, "test");

    FILE *file = fopen("filename", "r");
    if (file == NULL)
        error("Couldn't open file");
    
    free(test);

   ...

malloc()free() 现在如何处理这个只调用 exit(EXIT_FAILURE) 的错误。因为代码没有到达free(test)如果出现错误并且String测试没有被释放是否有问题?还是程序退出时自动释放?

【问题讨论】:

与您的问题无关的 Nitpick:test = "test"; 将测试指针更改为指向“test”,但它不会将“test”字符串复制到您刚刚分配的内存中,即可能是你想要的。那行应该是strcpy(test, "test"); @NickODell 是的,你是对的,但无论如何我都不使用此代码,这只是为了提出问题 这能回答你的问题吗? C potential memory leak caused by abnormally terminating program 【参考方案1】:

这个问题的答案是自动释放。

原因是对于 Linux 上的 C,内存总是以两种不同的方式跟踪。

每个程序都会跟踪它分配的内存,以及每个分配的大小。这是 malloc 级别的跟踪。 操作系统跟踪哪些内存属于哪个程序。这是页面级跟踪。

换句话说,如果一个程序未能释放一块内存,那么操作系统仍然知道那块内存属于该程序。程序退出时可以释放内存。

那么,如果操作系统可以为程序分配内存并释放它,为什么还存在 malloc 级别的跟踪呢?当 Linux 为程序分配内存时,它只能以称为“页”的 4KB 块的形式分配内存。如果你想分配 10 个字节来保存一个字符串,那么分配一个完整的页面会非常浪费,并且只使用前 10 个字节。出于这个原因,malloc() 以 4KB 页面向操作系统1 请求内存,如果您要求更小的部分,则将它们切割成更小的部分。然后,它会跟踪每个分配。

如果你忘记释放一块内存,而你的程序退出了,也没关系,因为操作系统无论如何都会释放内存。在错误路径中释放内存仍然是明智之举,因为有一天您可能想要更改程序,使其从错误中恢复,而不是立即退出。

1我在这里掩盖了一些细节。

【讨论】:

以上是关于malloc 和 free 如何处理错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理错误?

处理 Mongoose 验证错误——在哪里以及如何处理?

如何处理 ValueError:分类指标无法处理多标签指标和多类目标错误的混合

JavaScript中的内存泄漏以及如何处理

处理包/模块中的错误时如何处理Python异常

如何处理未捕获的错误:对象作为 React 子错误无效