(From threads:
Memory leak related to the std::string?
Memory leak?
)
Hi,
Firstly, thanks to those who answered my question. Secondly, I
am going to summarize the question and answers to that
question and also to similar ones from other threads (a
contribution to the "memory leak week" :). Some
questions (of mine) still remain...
My original question asked why the memory leak is detected
in the following code... (Microsoft VC++6 Ent.)
Quote:
> #include <crtdbg.h>
> #include <stdio.h>
> #include <string>
> int main(int argc, char * argv[])
> {
> std::string s("Hallo world!\n");
> printf("%s", s.c_str());
> _CrtDumpMemoryLeaks();
> return 0;
> }
Markus Sch?pflin explained...
Quote:
> This is no leak. When you reate an object of class string, it
> allocates memory for the characters. The memory is deleted
> when the object goes out of scope. In your case, the scope is
> the main function, hence the object is deleted when leaving
> the main function.
> By the way, you almost certainly don't want to use
> _CrtDumpMemoryLeaks() directly, as in the end, it simply dumps
> all memory that is currently allocated. Instead, look up
> _CrtSetDbgFlag() or use _CrtMemCheckpoint() and
> _CrtMemDumpAllObjectsSince().
which also explain why I did observe "Detected memory leaks!"
blocks with the content stored only in static const
std::string variables (class constant member variables in my
case).
John Keenan added...
Quote:
> Therefore the following should not show any memory leaks:
[...]
> int main(int argc, char * argv[])
> {
> {
> std::string s("Hallo world!\n");
> printf("%s", s.c_str());
> }
> _CrtDumpMemoryLeaks();
> return 0;
> }
[...]
Then, Chandler Gellar proposed...
Quote:
> I have found that the following is the best way to set up leak
> detection in a non-MFC app..
> 1) Your pre-compiled header file should contain this at the top:
> #define _CRTDBG_MAP_ALLOC
> #include <malloc.h>
> #include <stdlib.h>
> #include <crtdbg.h>
> 2) The first line of your "main" function should always read:
> _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
> Leaks will be dumped automatically on program termination --
> no need to call _CrtDumpMemoryLeaks().
As I do write the application with windows (the simple console
application was used just to show the problem) ane I use ATL
(which includes crtdbg.h, etc.), I've only added the following
line to the WinMain():
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
Some blocks of the memory-leak blocks disappeared (like those
related to the static const std::string variables) and some
remained -- they probably are the real memory leaks (errors
between my chair and my keyboard :)
Pieter Op de Beeck asked in the thread "Memory leak?"
Quote:
[...]
> #include <iostream>
> #include <crtdbg.h>
> void main ()
> {
> _CrtDumpMemoryLeaks();
> };
> giving me memory leaks [...]
Doug Harrison (
Visual C++ MVP) redirected my attention to
the mentioned thread where he explained:
Quote:
> <iostream> or the (draft) Standard C++ RTL define some
> global objects that allocate memory, while
> <iostream.h> doesn't, and you're dumping leaks before
> those globals are destroyed. Consequently, you get
> spurious leaks, and you're making exactly the same
> mistake MFC does. Let the CRT report leaks after it's
> destroyed static duration objects and run atexit()
> functions, which is the only right time to report
> leaks outside of regions bounded by
> _CrtMemCheckpoint(). Assuming you're using the MS CRT,
> I can't think of a single reason to call
> _CrtDumpMemoryLeaks().
[Notice the last sentence!]
Quote:
> You should use the checkpoint functions and other functions
> that deal with _CrtMemState.
> NB: To cause the CRT to automatically dump leaks at exit, you
> will need to use _CrtSetDbgFlag and _CrtSetReportMode, e.g.
> // Compile with cl -MDd -ZI b.cpp
> #include <crtdbg.h>
> void main()
> {
> _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)
> | _CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF
> | _CRTDBG_CHECK_ALWAYS_DF);
> _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
> _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
> _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
> _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
> _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
> _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
> new int[10];
> }
BTW, one should not use "void main()" (int would be better).
Quote:
> If you #include <iostream>, ...
[this was the difference which made the Pieter's code output the
message about memory leak detection]
Quote:
> ... you'll find that it doesn't increase the leak count. Also
> note that leaks reported at program exit may not be important,
> because there's little point in freeing memory that was
> dynamically allocated but needs to exist throughout the
> program's execution. Freeing this memory may slow program exit
> due to paging effects.
If I use the dynamic allocation a lot in my application, does
the last notice mean that I should always use mem-state and
checkpoint functions? Or can I distinguish that "little point
in freeing memory" case from the real (my own fault) memory
leaks?
Thanks,
Petr
--
Petr Prikryl, SKIL s.r.o., e-mail: prikrylp at skil dot cz
Please, don't reply via e-mail.