I have a number of derived classes, each derived from the same base class that has a static string. If I initialize the string to anything, a memory leak results. Why?
Printable View
I have a number of derived classes, each derived from the same base class that has a static string. If I initialize the string to anything, a memory leak results. Why?
I have no idea. Post some code that demonstrates the problem.Quote:
Originally Posted by paradoxresolved
I am willing to bet that you do NOT have a memory leak.
There is no hard fast rule as to the order of application exit. Your "leak detector" is probably running BEFORE the statics are being cleared up.
To confirm this put a brakpoint of the destructor of the item in question.
My thinking was somewhere on those lines. I thought perhaps since it was a static variable, and they exist regardless of whether or not any objects exist, they would be destroyed last as the program closes. I wasn't aware that the memory detector might execute too early though.
Is there a way to have the memory detector wait until later in the program?
If you dont like where the leak detector executs in your compilers runtime, then re-write the runtime. Otherwise simply do as I suggested.
Without seeing code, it is tough to say anything. TheCPUWizard has a good point as well.
Are you sure that the base class has a virtual destructor? Are you sure that you don't have initialization order problem? Or just about any other problem. Can't say without seeing code.
Oddly enough, the problem seems to be related to Visual C++ (which makes this the wrong forum). I was assigning a value to the static strings in the application's constructor. When I moved it to the application's InitInstance function, the memory leak stopped. I was also having a few other bizarre problems, such as the value of the static string being mysteriously erased shortly after being set, without good reason. This also stopped after moving it to the InitInstance function of the application.
Can anyone tell me why this happened? I was under the impression that static variables were global across all appropriate instances. Where I set their values shouldn't matter.
You will have to show code. Why are you being so mean to us. Posting questions and not the relevant code.
However, look at this thread for a specific problem with std::string - don't know if there's a patch but there is a chance you are working without it (or it just isn't there) and you need to take care - Reassignment of basic_string. This is probably just VC++ 6.0 specific.
Sorry. I wasn't trying to be mean. I'm being paid to create this code; I'm not allowed to post it. It's not top secret or anything, but my employer is super paranoid. :(
Then take the time and duplicate the problem with a small sample program. Here is your original problem, as stated in the first post:Quote:
Originally Posted by paradoxresolved
OK, so create a dummy foo, foo1, foo2, foo3, etc. classes, derived in whatever way, create a static string, and duplicate the memory leak. If the problem can be easily stated, then supposedly the issue can be easily duplicated. If it can't be duplicated, then there is much more than what the original post suggests the issue is.Quote:
I have a number of derived classes, each derived from the same base class that has a static string. If I initialize the string to anything, a memory leak results. Why?
Taking the time to do these steps before posting a question should be followed by anyone. Then the issue of
1) "it's my code from work" never has to be brought up,
2) It saves us time from having to pry code out from the poster, and
3) It more than likely will result in not posting any question here, since taking the time to duplicate it with a smaller example reveals the error to you.
Note how the regulars here practically never post questions concerning memory leaks. A good part of the reason is that we follow the steps above, as any good programmer does. The downside is that since we never post questions, new people believe we know the answer to their memory leaks without seeing any code. Of course this is not the case without seeing code that reproduces it.
Regards,
Paul McKenzie
Perhaps your employer should switch to decaf. Anyway, as Paul said you could give us a sample. It only takes a few minutes, using the visual studio wizard, to create a simple hello world application or dialog application which reproduces a similar problem.Quote:
Originally Posted by paradoxresolved
By the way; your employer is paying YOU, not us, to write this code. Nobody on this message board has any stake in your company, that we are aware of and therefore nobody is going to spend hours of their day guessing as to what your problem might be. Show us some code and some professional courtesy and someone might return the favor and help you out.
Good sirs, I am not trying to waste your time or upset you. I would not have posted this if I hadn't already tried to replicate it in a sample program. I've tried replicating it, but I haven't been able to. The following is basically what my classes are:
All the action starts in the App.cpp file, which looks like this:Code:/* header files */
class FooBase
{
public:
FooBase();
virtual ~FooBase();
static string staticstring;
};
class FooDerived : public FooBase
{
public:
FooDerived();
virtual ~FooDerived();
void Initialize();
};
class FooCover
{
public:
FooCover();
virtual ~FooCover();
shared_ptr<FooBase> pBase;
FooDerived* pDerived;
};
/* source files */
// FooBase.cpp
string FooBase::staticstring;
FooBase::FooBase()
{
}
FooBase::~FooBase()
{
}
//FooDerived.cpp
FooDerived::FooDerived()
{
}
FooDerived::~FooDerived()
{
}
void FooDerived::Initialize()
{
staticstring = "Who da foo?";
}
//FooCover.cpp
FooCover::FooCover()
{
pBase.reset(new FooDerived);
pDerived = static_cast<FooDerived*>(pBase.get());
pDerived->Initialize();
}
FooCover::~FooCover()
{
}
In the App.cpp file, I have three breakpoints:Code:// The one and only theApp. . .
FooCover TheFooCover; // FooBase::staticstring value set during FooCover constructor
StaticStringLeakApp theApp; // First break point placed here. staticstring exists and is ok.
StaticStringLeakApp::StaticStringLeakApp()
{
int BreakPoint2 = 0; // Second breakpoint. static string still exists
}
BOOL StaticStringLeakApp::InitInstance()
{
int BreakPoint3 = 0; // Third breakpoint. static string gone!!! memory leak!!!
AfxEnableControlContainer();
//...
}
1) The first breakpoint is when the StaticStringLeakApp is declared. By this point, FooCover has already initialized FooDerived, which sets the string. The string exists fine here. No problems.
2) The second breakpoint is in the App constructor. The string still exists and all is well (in both the sample program and in my actual project)
3) The third breakpoint shows the problem. In the sample program (attached), the string still exists and all is still ok, BUT IN MY PROJECT, THE STRING IS GONE!! The only way I can avoid this is to call the derived class's Initialize function at any point AFTER the third breakpoint.
I don't understand how a memory leak can even exist since I don't use "new" anywhere. Presumably it is used internally in the string class, but I'm not knowleable of the internals. I also don't know what the computer is doing between App::App() and App::InitInstance(), which appears to be where the problem is occuring. Is something happening between these two functions to inadvertently cause some other aspect of my project to execute?
Is there a way to make my debugger pause whenever the string is being changed? That would help to nail this down.
EDIT: I should also mention that my project has static integers, doubles, and booleans, which behave normally. The problem is only with the strings.
The timing of static initialization and destruction is controlled by the runtime. When an app exits main(), it is indeterminate if static values exist if accessing them from other static objects. That is the C++ explanation.
Since this is the non-Visual C++ forum, things like "InitInstance" are just normal member functions that has no meaning to non-MFC persons looking at the code -- a preferable example would be one with traditional C++ with a main() function, and the module names clearly specified.
Having said this, I would believe that if you tried to pinpoint where the string is destroyed, it may be educational, but it still won't help you if you kept the string as just a static string. You are more than likely relying on the timing of initialization/deinitialization of statics after the main() has exited, so you'll just be going around in circles trying to fix it (your fix may work sometimes, then it may not work other times).
To prevent this, an ugly solution is to keep the static string alive by creating it dynamically with "new" (declare it as a static pointer to a string), so it never gets destroyed by the runtime. On app termination, i.e. when you know you don't need it any more, then you call delete.
Regards,
Paul McKenzie
Hi,
Where is the code for reset() and get() functions of base class , and whats the use of these functions ?
in your origional application is it base class derived from any other class like CObject or something else ????
some times unloading dll's results in dumping false memory leaks.
as the destructor or Memory release code executes after that...
by the way which debugger you are using , are you claiming memory leaks on the basis of VS Debugger memory dump.
-Anant
reset() and get() are not members of the base class they are members of boost::shared_ptr. pBase is a boost::shared_ptr<FooBase>Quote:
Originally Posted by anantwakode