Memory leak C++

2020-05-20 06:08发布

I just wrote a code in C++ which does some string manipulation, but when I ran valgrind over, it shows some possible memory leaks. Debugging the code to granular level I wrote a simple C++ program looking like:

#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
        std::string myname("Is there any leaks");
        exit(0);
}

and running valgrind over it I got:

==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

Then it struck me that we have forcefully exited (which i performed in my original C++ code as well). Now the problem is that I want to exit from the program as my previous old code waits for the exit status of the new code. For e.g binary a.out waits for the exit status of b.out. Is there any way to avoid the memory leaks, or should i really worry about the memory leaks as the program is already exiting at that point.

This also raise another question for me, is such a code harmful?

#include<stdio.h>
#include<cstdlib>
int main()
{
        char *p=(char *)malloc(sizeof(char)*1000);
        exit(0);
}

10条回答
放荡不羁爱自由
2楼-- · 2020-05-20 06:13

To add a different opinion.

Such code is not harmful hat all. The OS will care for everything when the process terminates. Everything else results in an unstable OS. Just ensure that your persistent data (files, ...) is consistent.

To go a bit further and provocatively states, explicitly freeing memory on program exit can be harmful.

  1. Program exit takes longer (Did you ever get annoyed to wait for a program to exit until the computer shuts down?)
  2. The correct order of destruction is not always trivial, especially with 3rd party components (I remember some programs that likely crash on exit)
  3. The OS may not let you free memory after leaving main(*) and kill your program instead

Do you risk this just to make Valgrind give you a specific output?(**)


(*)

#include<iostream>
using namespace std;
std::string myname("Is there any leaks");
int main() {
        exit(0);
}

(**) Well, of course the output of any memory analyzer is more useful without "noise". What about only freeing memory explicitly on exit in debug mode?

查看更多
▲ chillily
3楼-- · 2020-05-20 06:14

If you'd like to break an execution and pass a return code without surpassing destructors, throw an exception, and extract the return value from the exception in main().

查看更多
爷、活的狠高调
4楼-- · 2020-05-20 06:16

At the time your process is actually exiting, as when main() exits, the OS will reclaim all resources allocated to your application either way. How you exit isn't so important - at least with regard to dynamic memory.

If you have some distributed database connection open or something, you should use atexit() handlers to close it, and forceful termination with straight-up exit may make them not run which would be bad - but as far as your OS resources are concerned you're probably okay.

You should also always make sure you release (manual) file locks and similar things as they may not go away due to a process exit.

查看更多
该账号已被封号
5楼-- · 2020-05-20 06:19

If the program is exiting, you do not have to worry about memory which was allocated with malloc or new. The OS will take care of it - anything in your process' virtual address space exclusively will go away when the process dies. If you're using shared memory or named pipes it could still be a concern.

查看更多
劳资没心,怎么记你
6楼-- · 2020-05-20 06:21

Use return 0; instead of exit(0); at the end of main. The use of exit circumvents the execution of the destructors.

查看更多
聊天终结者
7楼-- · 2020-05-20 06:21

In most cases, it's worth cleaning up after yourself, for the many good reasons already given: better maintainability, better utility from checking tools and so on.

If there are other functional reasons to clean up, maybe your data is saved to a persistent store, then you have no choice - you must clean up (although you might want to reconsider your design).

In some cases however, it may be better to just exit and "leak".

At the end of a program, your process is going to exit. When it does so, the operating system will recover any memory allocated by your program and in some cases it can do this much more quickly.

Consider a large linked list, where each node is dynamically allocated, and carries a substantial dynamically allocated structure. To clean this up you must visit each node and release each payload (which in turn may cause other complex structures to be walked).

You may end up performing millions of memory operations to run through such a structure.

The user wants to exit your program, and they sit there for 10s of seconds waiting for a bunch of junk processing to happen. They cannot possibly be interested in the result - they're quitting the program after all.

If you let this "leak", the operating system can reclaim the entire block of memory allocated to your process much more quickly. It doesn't care about the structures and any object cleanup.

http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx

Ultimately you must understand what your tools are telling you, to be sure you're using them properly.

查看更多
登录 后发表回答