Reputation: 432
So when exit(0)
happens, the strings are magically cleaned up, and valgrind
reports no leaks.
When exit(EXIT_FAILURE)
occurs, which it can at multiple points, valgrind
reports "possible leaks" for a bunch of C++ strings I created.
How can I clean them up when I know that exit_failure happens?
edit: I am referring to strings I created like this:
line 22 string include = "#include";
Valgrind:
==42430==
==42430== HEAP SUMMARY:
==42430== in use at exit: 100,201 bytes in 22 blocks
==42430== total heap usage: 33 allocs, 11 frees, 101,121 bytes allocated
==42430== 33 bytes in 1 blocks are possibly lost in loss record 6 of 22
==42430== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==42430== by 0x4EF2568: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==42430== by 0x4EF2676: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==42430== by 0x4EF42D5: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==42430== by 0x401C5A: processOneFile(std::istream&, std::ostream&, Node*, std::string) (include.cc:22)
==42430== by 0x402497: processOneFile(std::istream&, std::ostream&, Node*, std::string) (include.cc:99)
==42430== by 0x402C82: main (include.cc:172)
Upvotes: 1
Views: 403
Reputation: 33952
This is a comment that got out of hand.
To recap, Memory isn't much of a problem here. The program is terminating as a result of exit
, so leaks are leaks for at most a couple milliseconds. Yipeee!
What you really have to watch out for with exit is all those destructors that may have done important things not running, like flushing data to screen or files, politely hanging up network connections, and releasing resources that aren't managed by the OS. Unless the program must be terminated immediately with the subtlety of a headsman's axe, return
your way back to main
and exit normally.
If this isn't an option, or since this is C++ and anything that calls exit
should be pretty exceptional, throw
an exception and get all that stack unrolling goodness on your side.
@user I'd have to see your code to make good suggestions. You can test with something as simple as throw "Oh crap!";
, but typically I'll extend std::exception
something like this:
#include <iostream>
#include <exception>
#include <string>
class Failure: public std::exception
{
private:
std::string mErrMsg;
public:
Failure(std::string errMsg):mErrMsg(errMsg)
{
// does nothing
}
const char* what() const noexcept
{
return mErrMsg.c_str();
}
};
Then in place of exit
, I put: throw Failure("description");
. For example,
void function()
{
// does stuff
if (bad_stuff_happened)
{
throw Failure("description of the bad stuff that happened");
}
}
Then I wrap my main
or some other low-level function in a try/catch block to log the error. Here it is with main
:
int main()
{
try
{
function();
return EXIT_SUCCESS;
}
catch (Failure &excp)
{
std::cerr << excp.what();
return EXIT_FAILURE;
}
}
And the output of this is
description of the bad stuff that happened
in stderr.
I do not throw
for exit(0)
and I don't recommend that you do either. I don't recommend exit(0)
either. A good program result should be a very common, as in not exceptional circumstances, and be handled through the regular flow of code.
Upvotes: 1
Reputation: 1275
This doesn't sound like a memory leak. Once the process has exited the OS will reclaim the heap memory associated with it. When you free memory what you are generally doing is adjusting heap allocation accounting information local to your application.
Upvotes: 0