我们使用malloc在C中分配内存,在C++中使用new分配内存.我知道分配的内存必须在C中使用free并在C++中使用free来释放或返回给OS.如果在分配内存后忘记使用free/delete,则表示存在内存泄漏.
现在,我的问题是,这个内存是否仅在程序执行期间泄漏; 或者它是永久性泄漏/丢失还是重新启动系统后再次获得?实际上内部过程是什么?内存泄漏/丢失究竟意味着什么?
如果有人能够详细解释这个问题或者给我一些不错的参考资料,我将非常感激.
更新1
在阅读了一些答案之后,我了解到程序终止后内存会返回给OS /系统,如果是这样,为什么每个人都需要关心内存泄漏,为什么防止内存泄漏非常重要?
更新2
因此,应该防止内存泄漏,以便系统不会因为缺乏足够的内存来分配崩溃?
更新3
因此,在阅读完所有答案之后,我意识到内存泄漏是安静的重要问题,以防止系统崩溃.但是,对于像我这样的初学者,我怎么能确定我的程序是否完全没有内存泄漏.我尝试自由,删除如果我使用malloc,新的但有时,它会变得混乱.是否有任何工具或方法可以用来知道我的程序是否有任何内存泄漏?
更新4
在阅读答案之后,我现在已经了解了内存泄漏代码的重要性,更少使用新/删除,更多地使用STL,学习了新的东西,如RAII,valgrind和良好的编程实践.谢谢大家 :)
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.
操作系统将跟踪内存,一旦程序终止,将回收所有内存.它只是意味着您的应用程序丢失了一些已分配的内存.
请注意,这可能不适用于某些操作系统,但在任何Windows/unix/mac类型系统上都是如此
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),这已被证明是无价之宝!