Memory leak when using anything involving wxFileName - c++

I'm making use of wxWidgets in my program for directory management and compressing/uncompromising collections of files. As I've been building my file system, I've noticed that I get memory leaks every run. After a lot of testing, I realized that any time I use any functions related to wxFileName, I get a memory leak. I'm using wx widgets 3.0.1, and my standalone example is as follows.
#include <wx\filename.h>
int main()
{
wxFileName::Mkdir("Test");
return 0;
}
The result is the same if I make an instance of the wxFileName class.
How do I make wx widgets not create a memory leak? I want to be able to package large collections of files in one file, and read the data from them with various other libraries (via extracting the zip to a temporary folder and reading the data from there). I haven't been able to get any other library to zip/unzip entire folders, so I really need to be able to use wxWidgets without a memory leak.
I read in another thread that the visual studios debugger is falsely identifying the memory leaks, but I ran it through AQtime and it confirmed that there was indeed a memory leak.
The exact debug output involving the memory leak is as follows:
Detected memory leaks!
Dumping objects ->
{1087} normal block at 0x009B4BC0, 64 bytes long.
Data: <\+= d+= l+= t+= > 5C 2B 3D 00 64 2B 3D 00 6C 2B 3D 00 74 2B 3D 00
{1086} normal block at 0x009B4880, 772 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{1085} normal block at 0x009B4680, 28 bytes long.
Data: < H > 80 48 9B 00 C1 00 00 00 00 00 00 00 CD CD CD CD
Object dump complete.

After a bit of digging (it WOULD be the digging I did AFTER posting the question) I found that when you're using wxWidgets without creating a wxWidgets app object, you need to use the following two functions:
wxInitialize()
and
wxUninitialize()
So the fixed version of my code is as follows:
#include <wx/app.h>
#include <wx\filename.h>
int main()
{
wxInitialize();
wxFileName::Mkdir("Waka Waka");
wxUninitialize();
return 0;
}
I suggest if anyone is using wxWidgets purely for the file management to either call these functions in the constructor and destructor of whatever class handles files, or at the beginning and end of your program's main loop.

Related

Memory Leak (false positive) when an MFC applications uses a DLL

I develop a C++ Library (DLL). When I create a minimal MFC project (VS2017) that links with this DLL its okay. But as soon as any function of the library is used by the MFC application the debugger of the MFC project complains about memory leaks (many lines like the ones below):
Detected memory leaks!
Dumping objects ->
{2255} normal block at 0x000002A4B1F8C360, 48 bytes long.
Data: < > 10 BB F8 B1 A4 02 00 00 B0 BD F8 B1 A4 02 00 00
{2242} normal block at 0x000002A4B1F8BDB0, 48 bytes long.
Data: < > C0 C0 F8 B1 A4 02 00 00 F0 C2 F8 B1 A4 02 00 00
{2220} normal block at 0x000002A4B1F8C2F0, 48 bytes long.
Data: < > 80 C2 F8 B1 A4 02 00 00 10 C9 F8 B1 A4 02 00 00
These are false positives because it occurs also when only an empty test function of the library is called. Moreover this does not happen when the library is linked with a non-MFC project.
What can cause these warnings? Related information:
A VS2013 user said that he can avoid the warnings by changing the
character set of his MFC project. I have tested that in VS2017 but
get still warnings.
A VS2017 user said that the warnings are gone when he delay-loads
the DLL.
In the course of debugging I have compiled the DLL with CMake in order to use settings which are as standard as possible. But no change.

Setting endianness of VS debugger

I am using VS 2012 and programming in C++. I have a wide string
wchar_t *str = L"Hello world".
Technically I read the string from a file but I don't know if that makes a difference. When I look at str in the memory window it looks like this:
00 48 00 65 00 6c 00 6c 00 6f 00 2c 00 20 00 77 00 6f 00 72 00 6c 00 64 00 21 00
As you can see the string is stored in memory as big-endian.
When I hover my mouse over the string I get:
L"䠀攀氀氀漀Ⰰ 眀漀爀氀搀℀"
And after I reverse the endianness of str the memory looks like:
48 00 65 00 6c 00 6c 00 6f 00 2c 00 20 00 77 00 6f 00 72 00 6c 00 64 00 21 00 00
And the hover over looks like:
L"Hello, world!"
It seems that the debugger displays UTF-16 in little-endian by default. My program reads big-endian files so it is very tedious to keep reversing the endianness of all strings to debug them. Is there any way to change the endianness of the debugger's display?
Except for debug purposes I can do all my processing in big endian.
It's not only the debugger. The wchar_t function of Visual Studio are little endian as the host is. When you want to process the data you need to reverse the string endianess to little endian anyway.
It's worth to have this change even if you output the strings to a file with a different endianess. Strings are defined as a byte sequence, your endianess applied to a string looks strange anyhow.
Your best shot in getting this to work is to define your own type and create a debugger type visualizer for it (see Customizing the Visual Studio Debugger Display of Your Data, or here).
Or maybe you can quick-hack it by shifting the address by 1 byte in watch window.
You're working with a non-native string format that just happens to "feel" similar to the native format. So you are tempted to think there should be almost a way to do it. But to the debugger, it's just a foreign binary format. The debugger is not designed to handle foreign endianness just as it does not handle visualizing an OGG stream packet.
If you want to use available tools for manipulating native-endian Unicode strings, you'll need to convert to native-endian Unicode format.
As has been pointed out, VS uses the native endianness, which is
little endian on an Intel/AMD. The problem is that you're not
reading the strings correctly; you should imbue the
std::istream with a locale which reads UTF-16BE (since this is
apparently the encoding form you're trying to read).
std::istream (or rather the backing std::filebuf) will
automatically do the code translation on the fly when reading
and writing.
You can set the endianness of the Memory window using the context menu. Right-click in the Memory window and check "Big Endian".

Why doesn't leak detection give me line numbers?

I recently converted a program using raw pointers to std::shared_ptrs and wanted to ensure there was no memory leak. I looked at MSDN's Finding Memory Leaks Using the CRT Library page and followed the instructions to set up the report.
I begin by adding these lines to my file:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
and call the report with - _CrtDumpMemoryLeaks();
I am indeed using new to allocate my memory so, as the page suggests, I added...
#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif
#endif // _DEBUG
with no significant change in terms of a more precise location of the leak. Instead my report still looks like this:
Detected memory leaks!
Dumping objects ->
{158} normal block at 0x006F8458, 8 bytes long.
Data: < , > DC F6 2C 00 00 00 00 00
{155} normal block at 0x006FAD40, 40 bytes long.
Data: <L> > 4C 3E 17 01 03 00 00 00 01 00 00 00 CD CD CD CD
{154} normal block at 0x006FAB68, 16 bytes long.
Data: <d> > 64 3E 17 01 01 00 00 00 01 00 00 00 00 00 00 00
{149} normal block at 0x006FAC08, 40 bytes long.
Data: <L> > 4C 3E 17 01 03 00 00 00 01 00 00 00 CD CD CD CD
{148} normal block at 0x006FABB8, 16 bytes long.
Data: <d> > 64 3E 17 01 01 00 00 00 01 00 00 00 00 00 00 00
Object dump complete.
The program '[7152] List.exe' has exited with code 0 (0x0).
Unfortunately, the report is generated just prior to exit so it's not possible to see the leak in real time.
By looking at an answer to this question I noticed that I was not loading the pdb file due to the fact it's an empty project. So I followed the advice given here which did fix the pdb problem but failed to fix my issue.
The app was generated from an Empty Console Application, if that matters, and I'm running as an administrator.
Also I'm aware of external tools I could use but I often use computers that I don't have permission to add any to so getting VS to function properly is the ideal solution. Any help getting the report to show the line numbers of the leaks would be great.
Side Note:
I suppose a logical question to ask would be - If you're using managed pointers why do I still have memory leak? Well, I left a couple localized pointers that are only temp holders in sorts etc. that seemingly should not have caused an issue. So, I feel like I know where it is occurring but this is such a simple program I would like to know how this is accomplished so I can use it on larger ones. Thanks.
You need to make sure that the defines and the inclusion of stdlib are before any other includes in the application.
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif
#endif // _DEBUG
Should be the very first thing in your application.
You have to verify that all classes that you declare inside your project include crtdbg.h and the macro _crtdbg_map_alloc and the report at the end.
I found that I had to put the
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
in every file that might be the potential source of the allocation. I made the assumption that I only needed to do it in the main program where the
_CrtDumpMemoryLeaks();
is called.

Tracking memory leak

The situation:
I see around + 120kbytes increase when closing the class,
so when i close the clas few times memory increases - and i need to find out what is causing this.
Just looking for any good tip or trick of how to find out what is not freed/released with vstudio 2010 - any ideas?
Here's more clearly what i do ( very simplified )
class cSomeClass
{
cSomeClass();
~cSomeClass();
int Initialize();
void Deinitialize();
}
cSomeClass cCamera;
main()
{
Sleep(10000);
// Do Init / Deinit to find out if we are freeing the memory
while(1)
{
// Init camera
if(cCamera.Initialize()==0)
{
// Rest for a while
Sleep(1500);
cCamera.Deinitialize();
// Rest for a while
Sleep(1500);
}
}
}
I just did a small application to init / deinit the class object to see
in the 'task manager' if my memory for this application is returning to it's starting value - but it is not, it keeps incrementing every time i initialize the cSomeClass - so i believe i have something that is initialized but not freed in Deinitialize.
Update:
I don't think it is a simple memory growth, when application is launched it stabilizes itself after 10 seconds to let's say : 1MB of ram then when while(1) kicks in every Initialize i call i get +120kBytes in overall application memory ( checked in task manager ).
Update:
Thanks to Chad - got it sniffed with
_CrtDumpMemoryLeaks
Detected memory leaks!
Dumping objects ->
{76} normal block at 0x003F4BC8, 32 bytes long.
Data: <Logitech QuickCa> 4C 6F 67 69 74 65 63 68 20 51 75 69 63 6B 43 61
{75} normal block at 0x003F4B80, 8 bytes long.
Data: < K? > 20 4B 3F 00 00 00 00 00
{74} normal block at 0x003F4B20, 32 bytes long.
Data: < K? K? > 80 4B 3F 00 C8 4B 3F 00 CD CD CD CD CD CD CD CD
{70} normal block at 0x003F4A30, 8 bytes long.
Data: < )i > 0C 29 69 00 00 00 00 00
Object dump complete.
The most straight forward method is to use the Windows API functions for memory usage tracking, like _CrtDumpMemoryLeaks.
Using this in conjunction with _CrtMemCheckpoint can prove to be vital when tracking down stubborn leaks.
If you are using MFC, you can optionally define DEBUG_NEW, which adds additional tracking to the global new/delete operators, giving you file and line numbers for each allocation that leaks, this can be extremely helpful as well, but it doesn't work with some implementations of new (std::nothrow, for instance).
I'm not sure exactly what you mean by "closing the class", but if you're able to run your code in Linux valgrind is always a great option to track memory leaks. Purify also works well in Windows but it's $$.
Another approach is to try to stop the problem up front: Use smart pointers instead of raw pointers.
Finally make sure that you're actually seeing a leak and not just a memory growth up to a certain plateau.

Dump only a portion of memory in VS 2005

Does any one know if there is a way to dump only a chunk of memory to disk using VS? Basically, I want to give it an address and a length, and have it write the memory to disk. That way I can do a binary diff.
Thanks.
I'm kind of surprised VS won't let you do that from the Memory dump window...
You might be able to get what you want (or close to it) with the VS command window:
>Tools.LogCommandWindowOutput c:\temp\testdump.log /overwrite
>Debug.ListMemory /Count:16 0x00444B20
0x00444B20 00 00 00 00 00 00 00 00 13 00 12 00 86 07 19 00 ................
>Tools.LogCommandWindowOutput /off
If you're willing to use WinDBG, (or ntsd/cdb) you can use the .writemem debugger command to do exactly what you want.
I believe you can only save a complete binary minidump. However, you can use the Debug Memory window and copy/paste to a text file to do memory diffs.
OK, this I have tried in VS 2008, but I believe VS 2005 should allow the same:
If the memory is a string (if it doesn't contain zero bytes), you can put the following into a watch window: (unsigned char*)(ptr),1024 to see 1kB in the text visualizer. However, this stops at zero bytes, so if you have binary data, this won't work.