4

这个问题如标题所示:是否有可能在不使用任何内核特定手段(如 malloc、new 等)的情况下产生内存泄漏?

如果我将在一个包含很多元素的函数内创建一个链表,然后我将退出该函数而不清理列表,该怎么办。该列表将在不使用任何 malloc 调用的情况下创建,即

struct list_head {
     struct list_head *next, *prev;
}

能保证退出这个函数后所有的资源都会被释放吗?所以我可以自由执行一百万次,不会泄露任何东西?

主题:如果您不使用任何特定的 malloc 或 new 调用,您将不会遇到堆内存泄漏。绝不。那正确吗?

4

5 回答 5

12

泄漏总是与资源相关联。根据定义,资源是您手动获取并且必须手动释放的东西。内存是一个典型的例子,但也有其他资源(文件句柄、互斥锁、网络连接等)。

当您获取资源但随后丢失该资源的句柄以使任何人都无法释放它时,就会发生泄漏。较小版本的泄漏是一种“仍然可以访问”的情况,您不释放资源,但您仍然拥有句柄并且可以释放它。这主要是由于懒惰,但相比之下,泄漏始终是编程错误。

由于您的代码从不获取任何资源,因此它也不会有任何泄漏。

于 2013-09-24T08:56:16.287 回答
1

您在没有 malloc 或 new 的情况下应用的变量位于内存中的堆栈空间。所以当函数返回时,变量被取回。

另一方面,您使用 malloc 或 new 应用的内存位于堆空间。系统不关心你是否释放空间。在这种情况下,如果不使用 free 或 delete,就会发生内存泄漏。

于 2013-09-24T08:56:56.387 回答
1

主题:如果您不使用任何特定的 malloc 或 new 调用,您将不会遇到堆内存泄漏。绝不。那正确吗?

这种假设并不完全正确。问题是操作系统本身(或您必须依赖的其他第三方组件)也可能存在内存泄漏。在这种情况下,您可能不会主动调用 malloc,而是调用可能泄漏的其他(操作系统)函数。

因此,您的假设取决于您对此类事情的考虑程度。您可以争辩说操作系统/第三方实现在您的域之外,那么这个假设是正确的。如果您有一个定义明确的系统并且您的要求是您必须保证一定的正常运行时间,那么可能也必须考虑这样的事情。

所以这个问题的答案...

是否可以在不使用 malloc 的情况下造成内存泄漏?

... 是:

对的,这是可能的。

于 2013-09-24T09:47:52.513 回答
0

malloc()从堆中分配内存,而字符串和结构字面量( 和那些)的空间string1string2list_head编译时在堆栈中保留。

实际上,当进程退出时(至少在 *nix 系统中),内核将回收为程序(堆或堆栈)分配的任何内存。

我将内存泄漏定义为在堆上分配内存并且在程序退出时不释放它。这个定义实际上回答了你的问题。

有一些标准函数(如strdup)会在堆上分配内存,请注意它们。

于 2013-09-24T08:57:20.987 回答
0

您可以分配并忘记释放的资源的另一个示例:

如果您使用的是 OpenGL,并且在glGenBuffers()没有相应glDeleteBuffers调用的情况下调用了一百万次,那么您极有可能会耗尽 VRAM,并且您的图形驱动程序将开始泄漏到系统内存中。

我刚刚发生了这种情况。幸运的是,Visual Studio 的内存分析器很容易找到。它显示为外部进程进行的大量分配nvoglv32.dll,这是我的 NVIDIA OpenGL 驱动程序。

于 2017-12-26T15:42:19.603 回答