Dialogbox API leak?

Hi dear Experts:

I got memory leak error from Microsoft Visual studio 2015 diagnostic tools,

I am calling function:

DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), NULL, About, 0);

For each  time I call this API, I got leak if I set break point just before after this call, the diagnostic tools window shows the memory keep increasing.

I just wonder if this is a real leak or just a false alarm from the tool?

I found that if I set the parent window handle to be not a null, then there is no leak at this time.

I have attached the picture.

And I also attached the source code zip file.

Thanks for any help.
DialogboxAPILeak.png
TestWin32Dialog.cpp
TestWin32Dialog.h
TestWin32Dialog.rc
Resource.h
Evan LiSr SW EngineerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sarabandeCommented:
you should know that DialogBox is a c function provided by c winapi. because of that DialogBox cannot handle it owns memory management by means of destructors but requires the caller to provide enough (tempory) memory for to working properly. a leak detected in DialogBox always is in the responsibility of the calling function which didn't free all the buffers allocated after DialogBox has finished.

Sara
0
Evan LiSr SW EngineerAuthor Commented:
This is the first time that I hear that I need to free the buffer for dialogbox API, I did not allocate memory for this API, I do not have an handle or pointer to free the buffer, it is all handled by Windows. Please tell me further, if there is any way we can do it? Thanks.
0
Evan LiSr SW EngineerAuthor Commented:
Hi Sara, here are your answer in the over question thread:

but there is no resource load or memory allocation here

 and what is about:

1:wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));



Select all
 
Open in new window

 where did you free this resource?

 can you show a picture of the dialog or post the rc file?

 note, a visual c++ program uses a framework via stdafx.h. even if you use c code for dialog processing you still catch some automatic instantiations from framework. in the debugger things go worse since the debugger needs to make extra allocations for each variable you used. so if you detect leaks while running the program in debug mode but can't detect leaks in release mode, all your efforts are wasted.

 Sara
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Evan LiSr SW EngineerAuthor Commented:
I have attached the rc files and cpp files here,

Most code is generated from VS wizard, what I have changed is the about dialog box. Just open and close the about dialogbox, is not leak, if I changed the parent window to be null, then it is leaking.

Just use VS diagnostic tools for DialogboxParam, one statement.
The statement you said:

wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

Is not in any about box call back function. So it does not matter. If this leak, it does it for the whole program, it will not contribute to dialogbox leak.
0
Evan LiSr SW EngineerAuthor Commented:
OK, I have attached the picture of the program. It is a App Wizard generated program, I just changed the window handle for dialog box, and used VS diagnostic tool for only one statement, it gets consistent leak.
MemoryLeakTest.png
0
ZoppoCommented:
Hi Evan Li,

IMO you should try to find out if there's probably just a problem in the displayed diagnostic info. To verify the memory leaks you can try dumping them using _CrtMemCheckpoint and _CrtMemDumpAllObjectsSince, i.e. somhow like this:
bool CallDialog(HWND hWnd)
{
	_CrtMemState state = {};
	_CrtMemCheckpoint(&state);

	INT_PTR nResponse = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), NULL, About, 0);

	_CrtMemDumpAllObjectsSince(&state);
	return true;
}

Open in new window

In a DEBUG build this should ouput a list of all memory leaks produced by DialogBoxParam.

ZOPPO
0
sarabandeCommented:
you may try to create an mfc app dialog-based. you may use the app wizeard to copy the dialog resource from your current project to the mfc project. i wonder what the leak diagnostic would tell with this approach.

Sara
0
Evan LiSr SW EngineerAuthor Commented:
Hi, Zoppo:

I used Visual leak detector and CRT memory check APIs. both does not show memory leaks,

I did my test again, Here is what I have got:

Dumping objects ->
Object dump complete.
Dumping objects ->
Object dump complete.
Dumping objects ->
Object dump complete.
Dumping objects ->
Object dump complete.

But in diagnostic tools, it indicated that the memory keep getting up.
0
Evan LiSr SW EngineerAuthor Commented:
MFC code:

      CAboutDlg aboutDlg;
      aboutDlg.DoModal();

does not have a leak from diagnostic tools.
0
sarabandeCommented:
as told when creating the window you were loading some resources which in my opinion were not freed by your code.

about dialog only should be tested after you opened it at least once (in your menu). mfc Dialogs load their resources in OnInitDialog which was virtually called as a response to WM_INIT_DIALOG message. since you have the mfc code you could debug what happens when a dialog was created and when it finally was destroyed. note, the creation and the destroying is a two-step action.  the final freeing happens in OnDestroy and OnNcDestroy.

Sara
0
ZoppoCommented:
ok, that's really strange, I can reproduce it too now.

@Sara: to reproduce it you can simply create a Win32 (none-MFC) app from the scratch, it looks very similar to the code attached above. When debugging this app no memory leaks are shown when taking snapshots before and after showing the About-dialog.

BUT: As soon as you use NULL instead of hwnd in the call to DialogBox in WndProc the behavior changes and the diagnostic tool shows memory leaks between snapshots taken before and after showing the About-dialog:
snapshots taken after showing and closing the About-dialogHere's a bit more info about the leak between the last two snapshots:
memory leak infoI have no idea why passing NULL as parent window leads to this problem, but I fear there's not a lot you can do against because it happens quite deep within Windows API calls (I attached a screenshot of the call-stack because unfortunateley the diagnostic tool's view doesn't have a function to copy/export the stack as text).

@Evan Li: IMO you only have two possibilities:

1. Change the code to use hwnd instead of NULL again. (BTW: why do you want to use NULL here at all?)
2. Live with the memory leak. It's only 24 bytes each time the dialog is opened, so it's extremely unlikely this will ever lead to a problem.

Best regards,

ZOPPO
memleakstack.png
1
Evan LiSr SW EngineerAuthor Commented:
Thank you Zoppo,

Here is my Question,
1>I have MS Diagnostic tool, which can report me the memory leak
2>I have Visual Leak Detector
3>I have CRT checkMemory APIs just as you suggested.

they do not produce the consistent result. Which tool I should trust?

Here you saw the situation that Visual Studio Diagnostic tools reported error, but CRT memory check API says no memory leak, I have situation that Diagnostic tool told me there is not leak but CRT memory check shows errors.

Which one to trust, In both situation, I could not find the root cause.

Thank you for your help again.
0
sarabandeCommented:
can we call 24 bytes not freed a leak? i would say only if the next calls again would allocate the same amount. you should see that a static instantiation of a 24 byte structure - for example to serve as a pseudo parent window - might be responsible for the growing.

Sara
0
ZoppoCommented:
ok, I did some more analyzing and think it is a real memory leak. I wrote a function to dump out some statistics about current allocation on the heap:
static void DumpHeapStatistics()
{
	_HEAPINFO hinfo = {};
	int nStatus;
	size_t nSize = 0;
	size_t nCount = 0;

	while ( ( nStatus = _heapwalk( &hinfo ) ) == _HEAPOK )
	{
		bool bUsed = ( hinfo._useflag == _USEDENTRY );
		if ( bUsed )
		{
			nSize += hinfo._size;
			nCount++;
		}
	}

	TRACE( "*** Heap size: %Ii, block count: %Ii ***\n", nSize, nCount );
}

Open in new window

Then I changed the code where I open the dialog to this:
    case IDM_ABOUT:
	{
		_CrtMemState state = {};
		_CrtMemCheckpoint( &state );

		DumpHeapStatistics();

		DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), NULL, About);

		DumpHeapStatistics();

		_CrtMemDumpAllObjectsSince( &state );
	}

Open in new window

Then I started the application and opened and closed the dialog several times - here's the output:
d:\projects\test\testleak.cpp(133) : *** Heap size: 143220, block count: 798 ***
d:\projects\test\testleak.cpp(133) : *** Heap size: 144620, block count: 804 ***
Dumping objects ->
Object dump complete.
d:\projects\test\testleak.cpp(133) : *** Heap size: 144132, block count: 804 ***
d:\projects\test\testleak.cpp(133) : *** Heap size: 144156, block count: 805 ***
Dumping objects ->
Object dump complete.
d:\projects\test\testleak.cpp(133) : *** Heap size: 144156, block count: 805 ***
d:\projects\test\testleak.cpp(133) : *** Heap size: 144668, block count: 806 ***
Dumping objects ->
Object dump complete.
d:\projects\test\testleak.cpp(133) : *** Heap size: 144180, block count: 806 ***
d:\projects\test\testleak.cpp(133) : *** Heap size: 144204, block count: 807 ***
Dumping objects ->
Object dump complete.
d:\projects\test\testleak.cpp(133) : *** Heap size: 144204, block count: 807 ***
d:\projects\test\testleak.cpp(133) : *** Heap size: 144228, block count: 808 ***
Dumping objects ->
Object dump complete.
d:\projects\test\testleak.cpp(133) : *** Heap size: 144228, block count: 808 ***
d:\projects\test\testleak.cpp(133) : *** Heap size: 144252, block count: 809 ***
Dumping objects ->
Object dump complete.
d:\projects\test\testleak.cpp(133) : *** Heap size: 144252, block count: 809 ***
d:\projects\test\testleak.cpp(133) : *** Heap size: 144276, block count: 810 ***
Dumping objects ->
Object dump complete.
d:\projects\test\testleak.cpp(133) : *** Heap size: 144276, block count: 810 ***
d:\projects\test\testleak.cpp(133) : *** Heap size: 144300, block count: 811 ***
Dumping objects ->
Object dump complete.

Open in new window

It seems the first time the dialog is called more 'leaks' are produced (6 blocks, 1400 bytes), each following call adds one 24 bytes block.

I have no idea why the _CrtDump... functions don't report this, but IMO there really is a memory leak, anyway with just 24 bytes for each time a dialog is opened I think it can be ignored.

ZOPPO
1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Evan LiSr SW EngineerAuthor Commented:
Thank you both Zoppo and Sara.

This should be an API bug. But we need to work around it.

Thank you again.
0
Evan LiSr SW EngineerAuthor Commented:
Hi Zoppo,
I have a question in another thread that is related to this one.  From time to time, I got leak, says "unresolved allocation" in Visual studio, I could not find where my code is wrong if you look at call stack. How are you going to do this in this situation?
0
sarabandeCommented:
yes, you should close it as the last comment pointed to this thread.

Sara
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.