MichaelWard wrote:In my opinion though, I doubt your program is crashing due to memmory leaks. Nowadays, computers have so much memmory that it takes a lot of effort to use up all the memmory and cause the program to crash. (Assuming you are not actively trying to eat all the memmory). Your crash probably comes from pointers and accessing invalid memmory.
Michael, I completly agree with you. But taking your very sensible note as an basic hypothesis I have interpreted a fatal "memory leak" from the initial post as the most common memory management error which is freeing dangling pointers (pointers that are not pointing to an allocated memory block).
MichaelWard wrote:Are you trying to link to the wxWidgets DLL that gives you all the classes, or did you create your own DLL with new classes etc derived from wxWidgets classes?
I have tailored my wxWidget library by simply removing components of wxWidgets that I don't use (zip, Jpeg, png,...), by changing the setup.h file (no other files were harmed). I have faster compilation and linking by doing this. But I added nothing in the wxWidget library.
MichaelWard wrote:I currently dynamically link my wxwidget programs to the wxWidget DLL as opposed to statically linking them. I also link my widgets programs to various other DLL's.
I am very interested to know how you succeed to avoid allocating wxString in the DLL and freeing it your own code (I suppose you don't use the wxUSE_STL).
In fact when you allocate a string its constructor inlines a call to StringBase constructor:
Code: Select all
wxString(const wxChar *psz) : wxStringBase(psz ? psz : wxT("")) { }
Then the base constructor inlines a call to InitWith
Code: Select all
wxStringBase(const wxChar *psz){ InitWith(psz, 0, npos); }
which is finally a call to the corresponding DLL entry (the code of InitWith is not inlinable)
In this call the DLL entry allocates memory by calling malloc. This is the malloc that has been linked into the DLL. This malloc is managing its heap and provides a memory block inside this heap. All is perfect until now and you get a string buffer in a legal memory block.
But then you want to delete the string (I don't care if the string was allocated on the stack or the heap; that does not matter). This calls the implicit (no code) string destructor which is inlined in a StringBase destructor call that inlines a call to Unlock:
Code: Select all
~wxStringBase() { GetStringData()->Unlock(); }
void Unlock() { if ( !IsEmpty() && --nRefs == 0) free(this); }
This inlines in turn a call to free.
The pointer passed to free is actually the pointer that had been returned by the malloc so all seem perfect. BUT this time free is called in your code. You are not in the DLL this time. So you call the free linked in your EXE that is working on the heap of your EXE that is distinct of the heap of your DLL. So you try to return the memory block of a heap to another heap. Usually this does not crash. But if you are not lucky this does !
So I really don't know how to force the same level of inlining in contructor and destructor cases because you must always free the memory where you have allocated it. Practically I don't know how to enforce that. It is my question! How this works in your code? Did you check that your heaps (DLL and EXE) are not mixing in your application.
Note that the malloc / free pattern is the only case I know of procedures used in your code and in the DLL that refers to static variables. But there may be other cases of such duplication between the DLL and the EXE.
PS: when I replace the DLL by a static link (which I did when I gave up trying to force the right inlining) all my memory errors disappear (I know that this is not a proof with such kind of memory errors but I find this is an additional convincing clue that the DLL is responsible of the anomaly).
Sorry to have been so long but I felt a detailed explanation was necessary to understand such a subtle error.
-----------------------
tan wrote:One possible issue is using different C-runtime libs (under Windows, for example, debug/release/dynamic/static) in app and DLLs and using actually bad practice to allocate memory in one place and to free it in another.
As you can see above the problem is not to use 2 different libs but 2 different instances of the same lib (one linked in the DLL and one in the EXE)
-----------------------
loptr wrote:so don't forget to delete the heap objects!
as said above, please correct me if i'm wrong as this is a fundamental i'm counting on, and if i'm wrong there...
I did not check all in details but I think you are right. Though my current problem is not how we allocate/free the wxString but how wxString allocates/frees its internal buffer.