Glo*_*ior 45 c c++ valgrind memory-leaks
我刚刚在C++中编写了一个代码进行字符串操作的代码,但是当我运行valgrind时,它显示了一些可能的内存泄漏.将代码调试到粒度级别我编写了一个简单的C++程序,如下所示:
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
std::string myname("Is there any leaks");
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
并运行valgrind我得到:
==20943== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 26 from 1)
==20943== malloc/free: in use at exit: 360,645 bytes in 12,854 blocks.
==20943== malloc/free: 65,451 allocs, 52,597 frees, 2,186,968 bytes allocated.
==20943== For counts of detected errors, rerun with: -v
==20943== searching for pointers to 12,854 not-freed blocks.
==20943== checked 424,628 bytes.
==20943==
==20943== LEAK SUMMARY:
==20943== definitely lost: 0 bytes in 0 blocks.
==20943== possibly lost: 917 bytes in 6 blocks.
==20943== still reachable: 359,728 bytes in 12,848 blocks.
==20943== suppressed: 0 bytes in 0 blocks.
==20943== Reachable blocks (those to which a pointer was found) are not shown.
==20943== To see them, rerun with: --show-reachable=yes
Run Code Online (Sandbox Code Playgroud)
然后让我感到震惊的是我们已经强行退出(我也用我原来的C++代码执行).现在的问题是我想退出程序,因为我以前的旧代码等待新代码的退出状态.例如,二进制a.out等待b.out的退出状态.有没有办法避免内存泄漏,或者我真的担心内存泄漏,因为程序已经在那时退出.
这也为我提出了另一个问题,这样的代码有害吗?
#include<stdio.h>
#include<cstdlib>
int main()
{
char *p=(char *)malloc(sizeof(char)*1000);
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
swe*_*egi 65
使用return 0;
而不是exit(0);
在结束时main
.使用exit
绕过了析构函数的执行.
Sig*_*erm 63
如果你坚持使用exit()
:
#include<iostream>
int main(){
{
std::string myname("Are there any leaks?");
}
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
此外,从main
返回值返回时,将成为应用程序的退出代码.因此,如果要传递退出代码,请使用return exitCode;
in main()
而不是exit
.
关于那部分:
这也为我提出了另一个问题,这样的代码有害吗?
是的,因为这是一个坏的编程习惯.
操作系统将清除您未能释放的任何内存,因此只要您没有设法占用所有系统内存和页面文件,就不应该损坏操作系统.
但是,编写草率/漏洞代码可能会变成习惯,因此依靠操作系统来清理混乱是一个坏主意.
sbi*_*sbi 22
这也为我提出了另一个问题,这样的代码有害吗?
Run Code Online (Sandbox Code Playgroud)#include<stdio.h> int main() { char *p=(char *)malloc(sizeof(char)*1000); exit(0); }
它对现代操作系统没有害处,因为它们会在流程结束时自动关闭流程拥有的所有资源.
然而,它仍然是不好的做法,并且可能导致微妙且难以发现错误,经过几年的维护,代码慢慢变化,直到白天,这确实变得有害.我曾参与一些代码已有十年历史的项目,并且我已经学到了一些教训,其中一些相当苛刻.因此,即使目前没有出现问题,我也会避免编写这样的代码.
在大多数情况下,由于已经给出了许多好的理由,因此值得自行清理:更好的可维护性,更好的检查工具实用性等等.
如果还有其他功能原因需要清理,可能您的数据会保存到持久存储中,那么您别无选择 - 您必须清理(尽管您可能需要重新考虑您的设计).
但是,在某些情况下,退出并"泄漏"可能会更好.
在程序结束时,您的流程将退出.当它这样做时,操作系统将恢复程序分配的任何内存,在某些情况下,它可以更快地执行此操作.
考虑一个大的链表,其中每个节点都是动态分配的,并带有一个实质上动态分配的结构.要清理它,您必须访问每个节点并释放每个有效负载(这反过来可能导致其他复杂结构被移动).
您最终可能会执行数百万次内存操作以运行此类结构.
用户想要退出程序,他们会在那里停留10秒钟,等待一堆垃圾处理发生.他们不可能对结果感兴趣 - 毕竟他们正在退出计划.
如果你让这个"泄漏",操作系统可以更快地回收分配给你的进程的整个内存块.它不关心结构和任何对象清理.
http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx
最终,您必须了解您的工具告诉您的内容,确保您正确使用它们.