Re: Memory leak with static string
I am using Visual C++ 6.0, but I will soon be switching to a newer version. I imagine it's not the worse IDE in the world, but the debugger is about as helpful as a gun shooting in reverse. There are also some basic macros that are apparently missing (e.g. __FUNC__). Apart from that it has served me well.
Anyway, there is unfortunately no equivalent to main() in the dialog-based application. My understanding is that it starts in the App.cpp file, encounters the FooDerived statement, then goes into the App constructor, then goes into the App::InitInstance function. The dialog then gets activated within the App::InitInstance and for the rest of the time the code exists within subfunction called therein.
Apparently, initializing static variables prior to the InitInstance function is unpredictable. Correct? Your solution, "ugly" as it may be, appears to be only acceptable one. Thank you Paul.
Is there any way I can have this thread moved to the Visual C++ forum? Thank you all.
Re: Memory leak with static string
Quote:
Originally Posted by paradoxresolved
Is there any way I can have this thread moved to the Visual C++ forum? Thank you all.
Try contacting one of this forum's moderators (look for the names on the bottom of thread list). Send them a PM asking for redirecting it there as well.
Re: Memory leak with static string
I find this to be peculiar.
Code:
BOOL StaticStringLeakApp::InitInstance()
{
int BreakPoint3 = 0; // Third breakpoint. static string gone!!! memory leak!!!
AfxEnableControlContainer();
//...
}
So you are saying that the application is leaking memory during initialization? The static string is a member of the FooCover class which seems to have a global scope. I thought the memory leak was occuring on exit. The comment in your example seems confusing. I'm not sure I understand the specific problem you are having after reading the comments in your example.
Re: Memory leak with static string
In the sample program (see attached) the string is still exists and there is NO memory leak at breakpoint 3. All is working as I would expect. In my project, however, the string is gone and a memory leak exists at breakpoint 3. I can't reproduce the leak and it is really annoying me.
The fact that a static member has global scope is exactly what's confusing me. The string is disappearing with a memory leak in the MIDDLE of the program between the end of App::App() and App::InitInstance(). No part of my project even contain "new string." I couldn't deliberately cause this error if I wanted to.
Anyway, I took Paul's suggestion and dynamically created the static strings, and it seems to have solved the problem. It's ironic that I solved a memory leak by dynamically allocating memory.
Re: Memory leak with static string
Quote:
Originally Posted by paradoxresolved
In the sample program (see attached) the string is still exists and there is NO memory leak at breakpoint 3. All is working as I would expect. In my project, however, the string is gone and a memory leak exists at breakpoint 3. I can't reproduce the leak and it is really annoying me.
The fact that a static member has global scope is exactly what's confusing me. The string is disappearing with a memory leak in the MIDDLE of the program between the end of App::App() and App::InitInstance(). No part of my project even contain "new string." I couldn't deliberately cause this error if I wanted to.
Anyway, I took Paul's suggestion and dynamically created the static strings, and it seems to have solved the problem. It's ironic that I solved a memory leak by dynamically allocating memory.
Thanks for the clarification. CPUWizard's initial reply seemed to indicate that this was a problem during application shutdown, not during initialization. Until you posted your example, I didn't fully understand what type of problem you are having.
Also, I wasn't aware that the visual studio debugger printed memory leaks until shutdown. When you say that the "string is gone", I'm not sure what you mean. I don't see how that can be. How exactly did you confirm this? In your example the FooCover object is a global so I don't see how it would get destroyed at that point. So in your example, I do not see a memory leak. I feel your pain; seems like a tough problem but I just don't see how a static variable could disappear in the middle of a program. The idea of a memory leak seems nonsensical at this point. There isn't anything to leak. A leak is when memory exists that cannot be destroyed. Your saying that something is "disappearing". If a leak was occuring that means that the object is still there but there is no way to gain access to it anymore. So I am confused as to why you are classifying your problem as a "memory leak".
Re: Memory leak with static string
The debugger waits until the end of the program to indicate if there is a memory leak. To the best of my knowledge it does not alert me mid-program; I would be thrilled if I could get that to work. By stating that the string is "gone," I mean that the value of the string returns to "". When the memory leak is reported, however, it tells me the original values.
For example, if I set the static string to "This should not leak." the debugger (after exiting the program) will say that I have a memory leak and tell me the memory lost contains "This should not leak." At the breakpoint3, the value of the string is no longer "This should not leak" but rather is "". Since my debugger doesn't tell me exactly when the leak occured, I can only surmise that the two events are one and the same, especially since I never change the value of the static string after initialization. The string should never ever contain "" after I initialize it.
If I set the value of the string AFTER InitInstance, I never have a problem.
Re: Memory leak with static string
Quote:
Originally Posted by paradoxresolved
The debugger waits until the end of the program to indicate if there is a memory leak. To the best of my knowledge it does not alert me mid-program; I would be thrilled if I could get that to work. By stating that the string is "gone," I mean that the value of the string returns to "". When the memory leak is reported, however, it tells me the original values.
For example, if I set the static string to "This should not leak." the debugger (after exiting the program) will say that I have a memory leak and tell me the memory lost contains "This should not leak." At the breakpoint3, the value of the string is no longer "This should not leak" but rather is "". Since my debugger doesn't tell me exactly when the leak occured, I can only surmise that the two events are one and the same, especially since I never change the value of the static string after initialization. The string should never ever contain "" after I initialize it.
If I set the value of the string AFTER InitInstance, I never have a problem.
I'm not sure if the memory leak you are referring to has anything to do with whether a static string object has a particular value at some point in the program. I think that these are two different problems, personally. In your example, FooDerived's Initialize() method sets the string to some value (the static object was uninitialized, by default). In the program where your problem is occuring, I'm wondering at what point the string is initialized and if it is possible that somewhere along the lines it is getting reset to "". Or perhaps the string hasn't been initialized even though you think it should have been. Either way, I'm not sure what memory leaks have to do with *that* problem.
Re: Memory leak with static string
If it is *not* a bug in the application code, it could also be a memory over-write, this being much more severe.
Remember, "in the real world" [on a PC or MAC], the only (non-recurring) leaks that matter those that really require the destructor be called.
The memory will always be returned to the system at program exist...But if you have a control program for a nuclear reactor, which you intend to turn of when you exist the program (by implementing it in a destructor), then you could begin to develop a nice glow if that instance ever leaked.....
Re: Memory leak with static string
TheCPUWizard:
heh. . . No nuclear reactor here. Basically, you're saying that this memory leak is not significant because it occurs once, at program exit? Fine by me. :)
Kempofighter:
I understand your point. The two are not necessarily the same event. It's just frustrating because the string contains the appropriate value at one moment, and then loses it after InitInstance; at the end of the program then the memory leak error shows up. When I set the value of the string after InitInstance, its value remains the same and the memory leak disappears. Highly annoying.
Since this problem started, I've added other types of static variables, like shared_ptr<FooBase>. . . the same weirdness occurs. If I set the value of shared_ptr<FooBase> after InitInstance, all is well, and no memory leak shows up. Before InitInstance, the value gets lost and a massive memory leak occurs.
Interestingly, simple static variables, like static int, static doubles, and static boolean behave normally regardless of where their values are set. No memory leaks either way. It's just the complex data types and structures that cause problems. I'm convinced that it's MFC mischief.
For the moment, I'm just setting their values after InitInstance. Perhaps I'll eventually find the answer, but for now I'm stumped.
I requested to have the thread moved to Visual C++ forum, but the moderator said it was better to keep it here since I had too many responses on this forum.
If anyone finds out anything, please let me know. Thanks for the help everyone.
Re: Memory leak with static string
Quote:
Originally Posted by paradoxresolved
Interestingly, simple static variables, like static int, static doubles, and static boolean behave normally regardless of where their values are set. No memory leaks either way.
Note that pointers are also simple types, which is why using "new" didn't cause a problem.
For classes that have user-defined constructors and destructors, there is much more involved. At some point, indeterminate to you, the runtime must construct the global/static object, and again indeteminate to you, the object must have its destructor called after the main() exit point by the runtime.
Since the constructor and destructor are actual functions of the global/static object (and for std::string, memory is allocated and deallocated), what you're doing is something that really is different about C++ (as opposed to C), and that is user-defined code running before and after main() executes. That's why the rules are so hard to define when the runtime decides to instantiate a global or static object and when it's time to destroy such an object.
There are some general rules about static objects, but only in the context of where they are guaranteed to be initialized after main() has started.
Quote:
I'm convinced that it's MFC mischief.
For a Win32 program, the WinMain() is the entry point. Anything outside of WinMain() is basically the same thing as anything outside of main(). So if MFC somehow has placed code outside of the WinMain() entry point, and you're using it in some way (maybe InitInstance(), I don't know) then there is your explanation.
So there is a simple explanation, if you take the time to debug the code carefully. By debug, I mean go into MFC and see where WinMain() exits. When you see that happening, then any static objects are basically in a state where you won't be able to guarantee if they will exist.
Regards,
Paul McKenzie
Re: Memory leak with static string
I did a search for WinMain in my dialog based program. There were no results. This has contributed to my trouble. I understand your point though. For the moment, I've circumvented the problem by initializing everything after InitInstance, and it seems to work fine.