C,C++中的内存泄漏; 忘了做免费,删除

seg*_*ult 35 c c++

我们使用malloc在C中分配内存,在C++中使用new分配内存.我知道分配的内存必须在C中使用free并在C++中使用free来释放或返回给OS.如果在分配内存后忘记使用free/delete,则表示存在内存泄漏.

现在,我的问题是,这个内存是否仅在程序执行期间泄漏; 或者它是永久性泄漏/丢失还是重新启动系统后再次获得?实际上内部过程是什么?内存泄漏/丢失究竟意味着什么?

如果有人能够详细解释这个问题或者给我一些不错的参考资料,我将非常感激.

更新1

在阅读了一些答案之后,我了解到程序终止后内存会返回给OS /系统,如果是这样,为什么每个人都需要关心内存泄漏,为什么防止内存泄漏非常重要?

更新2

因此,应该防止内存泄漏,以便系统不会因为缺乏足够的内存来分配崩溃?

更新3

因此,在阅读完所有答案之后,我意识到内存泄漏是安静的重要问题,以防止系统崩溃.但是,对于像我这样的初学者,我怎么能确定我的程序是否完全没有内存泄漏.我尝试自由,删除如果我使用malloc,新的但有时,它会变得混乱.是否有任何工具或方法可以用来知道我的程序是否有任何内存泄漏?

更新4

在阅读答案之后,我现在已经了解了内存泄漏代码的重要性,更少使用新/删除,更多地使用STL,学习了新的东西,如RAII,valgrind和良好的编程实践.谢谢大家 :)

Bri*_*new 33

这是每个过程.进程退出后,分配的内存将返回到操作系统,供其他进程(新进程或现有进程)使用.

要回答您编辑的问题,您的机器中只有有限的内存.因此,如果您有内存泄漏,那么主要问题是内存不可供其他进程使用.次要但不可忽略的影响是,您的过程映像会增长,您将切换到光盘并且性能会受到影响.最后,你的程序将耗尽系统中的所有内存并失败,因为它无法为自己分配任何内存.

可以说,对于寿命短的小型进程,内存泄漏是可以容忍的,因为泄漏的内存数量很少而且寿命很短.

看看这个资源,可能会提供您所需要的更多信息.我们在这里讨论的是动态分配.


jal*_*alf 16

内存泄漏只是意味着您的应用程序无法释放它已分配的内存.一旦你的程序结束,由操作系统决定会发生什么.每个现代操作系统都会回收应用程序使用的所有内存,因此一旦您的进程终止,它就会被清理干净.

但是C/C++并不能保证操作系统能够做到这一点.在某些平台上,可能会在重新启动之前内存丢失.

所以内存泄漏的问题是双重的:

  • 系统可能需要重新启动以回收内存的一个平台.在大多数平台上,这是一个非问题,虽然泄漏一些其他资源类型仍可能导致问题.
  • 只要您的程序正在运行,它将分配它永远不会释放的内存,这意味着它将使用越来越多的内存.如果您的程序要运行很长时间,它可能最终使用机器上的所有可用内存,并随后崩溃.

许多短期运行的程序实际上忽略了内存泄漏,因为他们知道它很快就会被操作系统清理干净.据我所知,微软的C++编译器就是这样做的.他们知道,一旦调用了编译器,它最多会运行几分钟.(他们知道它运行在Windows,其中OS 回收内存,一旦进程终止)所以没关系,它在这里和那里泄漏一些内存.

至于如何避免内存泄漏,请不要创建它们.

每次使用new/delete时都有泄漏内存的风险,所以不要这样做.

当您需要数据数组时,请执行以下操作:

std::vector<char> vec(200);
Run Code Online (Sandbox Code Playgroud)

而不是这个:

char* arr = new char[200];
Run Code Online (Sandbox Code Playgroud)

前者同样有效,但您不必显式调用delete来释放它std::vector使用RAII在内部管理其资源.你应该做同样的-无论是使用像现成的RAII类vector,shared_ptr或几乎任何其他标准库或升压级,或通过编写自己的.

作为一般经验法则,除了负责管理该分配的类的构造函数/析构函数之外,您的代码不应包含任何新的/删除调用.

如果一个对象在构造函数中分配它需要的内存,并在析构函数中释放它(并正确处理复制/赋值),那么只要你需要它就可以在栈上创建一个类的本地实例,它不会,不能,泄漏记忆.

不在C++中泄漏内存的关键是不要调用new/delete.

  • 呃什么?Alexandrescu说C++应该支持范围,因为它们可能比迭代器更容易和更有效地处理.但这与vector无关*,与使用标准容器防止内存泄漏无关.重要的一点是,他不是反迭代者.他非常清楚他们是多么有用和强大.它们比没有迭代器好得多.他只是指出,支持范围将是一个进一步的改进.那你有什么建议?直到他们添加范围支持C++,我们应该回到C? (6认同)

jco*_*der 9

操作系统将跟踪内存,一旦程序终止,将回收所有内存.它只是意味着您的应用程序丢失了一些已分配的内存.

请注意,这可能不适用于某些操作系统,但在任何Windows/unix/mac类型系统上都是如此

  • +1表示这实际上是特定于平台的. (3认同)

Sha*_*hin 5

Re:用于检测内存泄漏的工具

如果您使用基于Linux的操作系统进行开发,可以尝试使用valgrind(http://valgrind.org/)来检测内存泄漏.

valgrind --leak-check=full ./compiled_binary
Run Code Online (Sandbox Code Playgroud)

如果您的程序是使用调试符号编译的(例如,对于gcc,请包含-g标志),valgrind也会告知您泄漏内存分配的确切代码行.这将极大地简化跟踪和修复泄漏的任务.

优点:它是免费的

缺点:AFAIK,它只适用于Linux

更新

http://valgrind.org/info/platforms.html所示,valgrind正被移植到其他操作系统(和平台),包括MacOSX,FreeBSD和NetBSD.

更新2

(稍微偏离主题但......)

使用valgrind的好处是它不仅仅检查内存泄漏.请参见http://valgrind.org/info/tools.html

我将buildbot配置为对我所有的夜间构建运行valgrind(和splint),这已被证明是无价之宝!