5

I have a program that is supposed to output info on its memory leaks. However, it is not working. Following is the program:

#include <crtdbg.h>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    FILE *out_file;
    int *a = new int;

    //Redirect the error stream to a file.
    freopen_s (&out_file, "Memory Leaks.txt", "w", stderr);

    //Turn on debugging for memory leaks. This is automatically turned off when the build is Release.
    _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE);
    _CrtSetReportFile (_CRT_WARN, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE);
    _CrtSetReportFile (_CRT_ERROR, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE);
    _CrtSetReportFile (_CRT_ASSERT, _CRTDBG_FILE_STDERR);

    return 0;
}

I am building in the DEBUG version, so the functions shouldn't be ignored. The compiler I am using is Visual Studio 2010. The program only creates a file "Memory Leaks.txt" but there is no content in the file. Any thoughts?

--EDIT--

I have updated the program to use a "proper File Handle" as suggested. The program still outputs nothing to the file.

--EDIT--

The problem was with closing the file. The following code now works.

#include <crtdbg.h>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    HANDLE hLogFile;
    int *a;

    //Open a file for output.
    hLogFile = CreateFile ("Memory Leaks.txt", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    //Turn on debugging for memory leaks. This is automatically turned off when the build is Release.
    _CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    _CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE);
    _CrtSetReportFile (_CRT_WARN, hLogFile);
    _CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE);
    _CrtSetReportFile (_CRT_ERROR, hLogFile);
    _CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE);
    _CrtSetReportFile (_CRT_ASSERT, hLogFile);

    //Create a memory leak.
    a = new int;

    //Don't close this file. Closing the file will cause the report not to be outputted.
    //CloseHandle(hLogFile);

    return 0;
}
GILGAMESH
  • 1,816
  • 3
  • 23
  • 33
  • 1
    I don't know these APIs at all, but seems strange that you're operating on `stdout` but passing flags with names containing `STDERR`. – Mat Jan 01 '13 at 17:16
  • Good catch. I changed that, but the output didn't change – GILGAMESH Jan 01 '13 at 17:17
  • The other thing I find puzzling is that you're apparently activating debug checks _after_ you've allocated the memory you're leaking. Just feels strange. – Mat Jan 01 '13 at 17:18
  • Well, the thing is, if I specify to output to `_CRT_MODE_DEBUG`, there isn't a problem, even if I allocated the memory before I activate debug checks. – GILGAMESH Jan 01 '13 at 17:20
  • Did you try the example specified here http://msdn.microsoft.com/en-us/library/5at7yxcs%28v=vs.71%29.aspx – benjarobin Jan 01 '13 at 17:25
  • That's not the problem. The problem is getting the output to a file, not specifying which type of output I want. – GILGAMESH Jan 01 '13 at 17:27
  • 3
    Do avoid closing the log file **before** the leak report is generated. In other words, don't close the file. – Hans Passant Jan 01 '13 at 17:42
  • OK, that seemed to work. – GILGAMESH Jan 01 '13 at 17:43
  • I'm upvoting everyone who answered for their contributions, and also marking JasonD as answer because his code was correct. – GILGAMESH Jan 01 '13 at 17:45
  • @HansPassant Yes, I should make that explicit in my answer... – JasonD Jan 01 '13 at 17:49
  • If you solved the problem in some way that's not covered in an existing answer, _post your own answer_ detailing the final solution, and accept it. – Lightness Races in Orbit Jan 01 '13 at 18:47

3 Answers3

6

Stop tying to redirect stderr or stdout in a GUI Windows app, and open a proper File Handle. it's a one-liner.

HANDLE hLogFile = CreateFile(L"Memory Leaks.txt", GENERIC_WRITE, FILE_SHARE_WRITE, 
  NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

//Turn on debugging for memory leaks. This is automatically turned off when the build is Release.
_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode (_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile (_CRT_WARN, hLogFile);
_CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportFile (_CRT_ERROR, hLogFile);
_CrtSetReportMode (_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile (_CRT_ASSERT, hLogFile);

And don't close the HANDLE before the reports are actually generated!

JasonD
  • 16,464
  • 2
  • 29
  • 44
0

Should be used to output stream stderr.

//Redirect the error stream to a file.
freopen_s (&out_file, "Memory Leaks.txt", "w", stderr);

Example can be found: http://msdn.microsoft.com/en-us/library/a68f826y%28v=VS.71%29.aspx

yvaschuk
  • 59
  • 2
0

try this instead

#include < crtdbg.h >
#define _CRTDBG_MAP_ALLOC
Eric Aya
  • 69,473
  • 35
  • 181
  • 253