当你在malloc之后没有自由时真的会发生什么?

这已经困扰了我很多年了。

我们都在学校教书(至少,我是),你必须释放分配的每一个指针。 但我有点好奇,关于不释放内存的真正代价。 在一些明显的情况下,例如malloc在循环或线程执行的一部分内被调用时,释放非常重要,这样就没有内存泄漏。 但请考虑以下两个示例:

首先,如果我有这样的代码:

int main()
{
    char *a = malloc(1024);
    /* Do some arbitrary stuff with 'a' (no alloc functions) */
    return 0;
}

这里真正的结果是什么? 我的想法是,这个过程死了,然后堆空间不管怎样都没有了,所以没有必要让free的呼唤(但是,我确实意识到无论如何都有关闭,可维护性和良好实践的重要性)。 我在这个想法中是否正确?

其次,假设我有一个程序,有点像一个shell。 用户可以声明像aaa = 123这样的变量,并将这些变量存储在某些动态数据结构中供以后使用。 很显然,你会使用一些解决方案来调用一些* alloc函数(hashmap,链表,类似的东西)。 对于这种类型的程序,在调用malloc之后永远不会释放,因为这些变量必须在程序执行期间始终存在,并且没有好的方法(我可以看到)使用静态分配的空间来实现这一点。 有一堆分配的内存,但只作为流程结束的一部分释放,这是不好的设计吗? 如果是这样,另一种方法是什么?


几乎每个现代操作系统都会在程序退出后恢复所有分配的内存空间。 我能想到的唯一例外可能就像Palm OS,其中程序的静态存储和运行时内存几乎相同,所以不释放可能会导致程序占用更多的存储空间。 (我只是在这里推测。)

所以通常情况下,除了存储空间超过您的运行时间之外,其中没有任何伤害。 当然,在你给出的例子中,你想保留一个可能被使用的变量的内存直到它被清除。

然而,一旦你不再需要它就可以释放内存,并释放你在程序退出时仍然存在的任何东西。 这更多的是了解你正在使用的内存,并考虑你是否仍然需要它。 如果你不跟踪,你可能会有内存泄漏。

另一方面,在退出时关闭文件的类似警告有一个更具体的结果 - 如果你不这样做,你写给它们的数据可能不会被刷新,或者如果它们是临时文件,它们可能不会完成后会被删除。 此外,数据库句柄应该有他们的事务提交,然后关闭,当你完成他们。 同样,如果您使用的是面向对象的语言,如C ++或Objective C,则在完成对象时不释放对象意味着析构函数将永远不会被调用,并且该类负责的任何资源可能不会被清理。


是的你是对的,你的榜样没有任何伤害(至少不是在大多数现代操作系统上)。 一旦进程退出,所有由进程分配的内存将被操作系统恢复。

来源:分配和GC神话(PostScript警报!)

分配神话4:非垃圾收集程序应该总是释放它们分配的所有内存。

真相:在经常执行的代码中省略释放导致越来越多的泄漏。 他们很少接受。 但在程序退出之前保留大部分分配内存的程序通常在没有任何干预解除分配的情况下执行得更好。 如果没有免费的话,Malloc更容易实现。

在大多数情况下, 在程序退出之前释放内存毫无意义。 无论如何,操作系统将回收它。 免费将触摸和页面中的死物; 操作系统不会。

后果:小心使用计数分配的“泄漏检测器”。 一些“泄漏”是好的!

这就是说,你应该尽量避免所有的内存泄漏!

第二个问题:你的设计是好的。 如果你需要存储一些东西,直到你的应用程序退出,那么可以使用动态内存分配来完成。 如果您不了解所需的大小,则无法使用静态分配的内存。


=== 未来的校对代码重用如何? ===

如果你没有编写代码来释放这些对象,那么当你可以依靠被关闭的进程释放的内存时,你将代码限制为只能安全使用......即一次性使用少量项目或“扔掉”[1]项目)......你知道什么时候该过程会结束。

如果写的是免费的()是你的所有动态分配的内存的代码,那么你在未来验证码,让别人在一个较大的项目中使用它。


[1]关于“抛弃”项目。 “抛弃”项目中使用的代码有一种不被丢弃的方式。 接下来的事情,你知道十年过去了,你的“抛弃”代码仍在使用)。

我听说过一些关于编写代码仅仅为了获得乐趣而使自己的硬件工作更好的人的故事。 他说“只是一种爱好,不会很大而且很专业”。 几年后,很多人都在使用他的“爱好”代码。

链接地址: http://www.djcxy.com/p/14113.html

上一篇: What REALLY happens when you don't free after malloc?

下一篇: Big array gives segmentation error in C