[SmartPtr] Memory Leak Perhaps

Dear all, (Sorry for cross-posting.) I have a container which stores boost::shared_ptr's. The container has a strange behaviour upon insertion of a SPECIFIC pointer into it. The insertion itself happens with no problem and I can successfully do all my desired operations. Yet, I receive the following strange Win32 exceptions when I'm done and my program is ending (i.e., after the last instruction in my main function): 1) When I run the program from the CodeBlocks IDE (GCC 4.5.1, MinGW, WinXP-SP3), a message box from the JIT debugger pops up which says: "An unhandled Win32 exception occurred in ... [29436]". 2) When I run the same program from MSCV2008, an MSVC++ Debug Library message box pops up which says: "Program ... File f:\dd\... Line 52 Exception _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)...". I call the above error messages strange because of the observations below: 1) The error reported by MSVC2008 refers to a file on my drive F: whereas, basically, I don't have such a drive on my system! 2) The CodeBlocks debugger (a GUI wrapped around GDB) runs the program with no problems over the debug sessions. Despite that, there are several "Program received signal SIGTRAP, Trace/breakpoint trap." messages in the GDB debug log. Unfortunately, I don't know how to locate the place where these are related to. 3) MSVC2008 has the same behaviour over the debug session. The output of debug session ends with "The program '[29312] EE1Debugger.exe: Native' has exited with code 3 (0x3)." (Please find a copy of the debug log at the P.S. if you're interested.) My first guess was a memory leak but I didn't spot anything which smells like that over numerous debug sessions. I'm generally dubious about that because I'm using shared_ptr's. Shallow copy can't be the problem either again 'cause I only insert shared_ptr's (from just-allocated dynamic memory) into my container. On the other hand, the problem only occurs upon insertion of a SPECIFIC entry into my container. Strangely enough, if I delete that specific entry manually before the end of my program, everything goes fine! I even checked the count of that specific shared_ptr and it was 1, i.e., I'm not deleting anybody else's memory. I am really confused and left with no clue... Any suggestions? P.S. 'EE1Debugger.exe': Loaded 'D:\...\EE1Debugger.exe', Symbols loaded. 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcr90d.dll', Symbols loaded. 'EE1Debugger.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC90.DebugCRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_597c3456\msvcp90d.dll', Symbols loaded. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f550.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. First-chance exception at 0x7c812afb in EE1Debugger.exe: Microsoft C++ exception: std::runtime_error at memory location 0x0012f5a8.. 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\user32.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\imm32.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\secur32.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\lpk.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\usp10.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\GDX32.dll', Binary was not built with debug information. 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\acaptuser32.dll', Binary was not built with debug information. 'EE1Debugger.exe': Unloaded 'C:\WINDOWS\system32\acaptuser32.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\uxtheme.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\MSCTF.dll' 'EE1Debugger.exe': Loaded 'C:\Program Files\Trusteer\Rapport\bin\rooksbas.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\version.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\shlwapi.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\psapi.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\shell32.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\ole32.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83\comctl32.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\comctl32.dll' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\MSCTFIME.IME' 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\PickWord.dll', Binary was not built with debug information. 'EE1Debugger.exe': Loaded 'C:\Program Files\Dell\QuickSet\dadkeyb.dll', Binary was not built with debug information. 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\hccutils.dll', Binary was not built with debug information. 'EE1Debugger.exe': Loaded 'C:\WINDOWS\system32\oleaut32.dll' The program '[29312] EE1Debugger.exe: Native' has exited with code 3 (0x3).

My first guess was a memory leak but I didn't spot anything which smells like that over numerous debug sessions. I'm generally dubious about that because I'm using shared_ptr's. Shallow copy can't be the problem either again 'cause I only insert shared_ptr's (from just-allocated dynamic memory) into my container.
It's not a memory leak, but memory corruption: it seems that you try to free some memory block twice.
On the other hand, the problem only occurs upon insertion of a SPECIFIC entry into my container. Strangely enough, if I delete that specific entry manually before the end of my program, everything goes fine! I even checked the count of that specific shared_ptr and it was 1, i.e., I'm not deleting anybody else's memory. I am really confused and left with no clue... Any suggestions?
Maybe you accidentally store a raw pointer to an object managed by shared_ptr. Or maybe your object internally allocates and frees some memory, which is also managed in some other place... I guess it's worth searching calls to "delete" and "free" in your code.

Dear Igor, Thank you very much for your suggestions.
It's not a memory leak, but memory corruption: it seems that you try to free some memory block twice.
Yes, I did think about that one too. And, that's why I monitored the use_count() of my shared_ptr.
On the other hand, the problem only occurs upon insertion of a SPECIFIC entry into my container. Strangely enough, if I delete that specific entry manually before the end of my program, everything goes fine! I even checked the count of that specific shared_ptr and it was 1, i.e., I'm not deleting anybody else's memory. I am really confused and left with no clue... Any suggestions?
Maybe you accidentally store a raw pointer to an object managed by shared_ptr.
Well, my only suspicion is about the fact that I store "this" pointers in my shared_ptr's. However, those objects are dynamically allocated by myself, namely, they are not of automatic storage type anyway. In other words, my row pointer and "this" -- which themselves are different objects -- both point to the same memory dynamically allocated by myself. Furthermore, my following observation goes against this guess: (This is available above too.)
Strangely enough, if I delete that specific entry manually before the end of my program, everything goes fine!
And, by this, I meant that if I call container.erase(bad_entry), everything goes fine. Now, if bad_entry accidentally points to somebody else's resources, and this causes trouble for the container clean-up, then, why can I erase it from my container and dismiss the nasty exceptions?
Or maybe your object internally allocates and frees some memory, which is also managed in some other place...
Actually it does allocate memory for other objects (which are stored in the same container). But, I have tested that and the result is that everything -- including this extra allocation -- works perfectly fine JUST if I drop the insertion of this very specific object in the same container.
I guess it's worth searching calls to "delete" and "free" in your code.
Thank God there are only very few instances of delete in my code. I've checked them up and none of them got touched over my debug sessions. Am I missing anything? I would especially be keen on knowing whether you see any problems in storing "this" pointers of my own dynamically allocated objects in shared_ptr's. TIA, --Hossein

Well, my only suspicion is about the fact that I store "this" pointers in my shared_ptr's. However, those objects are dynamically allocated by myself, namely, they are not of automatic storage type anyway. In other words, my row pointer and "this" -- which themselves are different objects -- both point to the same memory dynamically allocated by myself. Furthermore, my following observation goes against this guess: (This is available above too.)
Why do you need to use two semantically different pointers to point to the same piece of dynamic memory?
Actually it does allocate memory for other objects (which are stored in the same container). But, I have tested that and the result is that everything -- including this extra allocation -- works perfectly fine JUST if I drop the insertion of this very specific object in the same container. Am I missing anything? I would especially be keen on knowing whether you see any problems in storing "this" pointers of my own dynamically allocated objects in shared_ptr's.
You may need to show how "specific" the object is -- sometimes a few lines of code are better than paragraphs of words. Why do you need to put a "this" pointer in a shared_ptr? When you can get a hand on "this", you are in the member function of the class. Basically that means your instance has already been created. The client creating the instance should probably manage the life cycle of this instance. I would say it's normally the responsibility of the client to put the instance pointer into a shared_ptr if it's not allocated on the stack. Again, you may want to paste your code to make the discussion easier.

Hi Binglong,
Why do you need to use two semantically different pointers to point to the same piece of dynamic memory?
I actually don't need to have TWO pointers to the same location. ANY pointer to that location suffices. The reason why I use "this" for that purpose is that the client code calls a virtual function of the class through the pointer that I allocate (using new), and the actual insertion into the container happens from inside this virtual function. It is of course possible to change the design a bit so that the virtual function also takes the address (of my manually allocated memory) as an argument. However, I would be interested to know which exact difference between the semantics of ordinary pointers and "this" might be making the trouble here. Could you be more precise please?
The client creating the instance should probably manage the life cycle of this instance.
Sure. And, that's why I store smart pointers in my container.
I would say it's normally the responsibility of the client to put the instance pointer into a shared_ptr if it's not allocated on the stack.
Although this is possible indeed, I believe it would involve making my design a bit messy. See below.
Again, you may want to paste your code to make the discussion easier.
OK, nice suggestion. I have a hierarchy H of classes with the base B, where B* need to be stored in a container. Insertion of B*'s into my container needs non-trivial processing prior to their actual addition to the container. These pre-processings differ from class to class in the hierarchy. In order to manage this complexity thus, I have broken the pre-processing down into chunks. Each individual class in H handles its own entire insertion (including the pre-processing and the actual insertion). This is done via implementations of: virtual B::insert_me_into(container&) = 0; where classes derived from B have enough access to the container through some protected interface toolkit provided by B. Thanks, --Hossein

Hi! shared_ptr to this are dangerous. As soon as you do that twice you already have a problem. If you want to create shared_ptrs to this, use shared_from_this. http://www.boost.org/doc/libs/1_44_0/libs/smart_ptr/enable_shared_from_this.... Cheers, Benjamin On Monday 20 September 2010 02:27:22 am Hossein Haeri wrote:
Dear Igor,
Thank you very much for your suggestions.
It's not a memory leak, but memory corruption: it seems that you try to free some memory block twice.
Yes, I did think about that one too. And, that's why I monitored the use_count() of my shared_ptr.
On the other hand, the problem only occurs upon
insertion of a SPECIFIC entry into my container. Strangely enough, if I delete that specific entry manually before the end of my program, everything goes fine! I even checked the count of that specific shared_ptr and it was 1, i.e., I'm not deleting anybody else's memory. I am really confused and left with no clue... Any suggestions?
Maybe you accidentally store a raw pointer to an object managed by shared_ptr.
Well, my only suspicion is about the fact that I store "this" pointers in my shared_ptr's. However, those objects are dynamically allocated by myself, namely, they are not of automatic storage type anyway. In other words, my row pointer and "this" -- which themselves are different objects -- both point to the same memory dynamically allocated by myself. Furthermore, my following observation goes against this guess: (This is available above too.)
Strangely enough, if I delete that specific entry manually before the end of my program, everything goes fine!
And, by this, I meant that if I call container.erase(bad_entry), everything goes fine. Now, if bad_entry accidentally points to somebody else's resources, and this causes trouble for the container clean-up, then, why can I erase it from my container and dismiss the nasty exceptions?
Or maybe your object internally allocates and frees some memory, which is also managed in some other place...
Actually it does allocate memory for other objects (which are stored in the same container). But, I have tested that and the result is that everything -- including this extra allocation -- works perfectly fine JUST if I drop the insertion of this very specific object in the same container.
I guess it's worth searching calls to "delete" and "free" in your code.
Thank God there are only very few instances of delete in my code. I've checked them up and none of them got touched over my debug sessions.
Am I missing anything? I would especially be keen on knowing whether you see any problems in storing "this" pointers of my own dynamically allocated objects in shared_ptr's.
TIA, --Hossein
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (4)
-
Benjamin Sobotta
-
Binglong Xie
-
Hossein Haeri
-
Igor R