You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If you are debugging an MFC program, these debugging techniques may be useful.
30
+
If you're debugging an MFC program, these debugging techniques may be useful.
31
31
32
32
## <aname="BKMK_AfxDebugBreak"></a> AfxDebugBreak
33
33
MFC provides a special [AfxDebugBreak](/cpp/mfc/reference/diagnostic-services#afxdebugbreak) function for hard-coding breakpoints in source code:
@@ -46,8 +46,6 @@ On other platforms, `AfxDebugBreak` merely calls `DebugBreak`.
46
46
47
47
Be sure to remove `AfxDebugBreak` statements when you create a release build or use `#ifdef _DEBUG` to surround them.
48
48
49
-
[In this topic](#BKMK_In_this_topic)
50
-
51
49
## <aname="BKMK_The_TRACE_macro"></a> The TRACE macro
52
50
To display messages from your program in the debugger [Output window](../ide/reference/output-window.md), you can use the [ATLTRACE](/previous-versions/6xkxyz08(v=vs.140)) macro or the MFC [TRACE](/previous-versions/6w95a4ha(v=vs.140)) macro. Like [assertions](../debugger/c-cpp-assertions.md), the trace macros are active only in the Debug version of your program and disappear when compiled in the Release version.
53
51
@@ -78,25 +76,21 @@ TRACE( _T("This is a test of the TRACE macro that uses a TCHAR string: %s %d\n")
78
76
79
77
For more information on the **TRACE** macro, see [Diagnostic Services](/cpp/mfc/reference/diagnostic-services).
80
78
81
-
[In this topic](#BKMK_In_this_topic)
82
-
83
79
## <aname="BKMK_Memory_leak_detection_in_MFC"></a> Detecting memory leaks in MFC
84
80
MFC provides classes and functions for detecting memory that is allocated but never deallocated.
In MFC, you can use the macro [DEBUG_NEW](/previous-versions/tz7sxz99(v=vs.140)) in place of the **new** operator to help locate memory leaks. In the Debug version of your program, `DEBUG_NEW` keeps track of the file name and line number for each object that it allocates. When you compile a Release version of your program, `DEBUG_NEW` resolves to a simple **new** operation without the file name and line number information. Thus, you pay no speed penalty in the Release version of your program.
88
84
89
-
If you do not want to rewrite your entire program to use `DEBUG_NEW` in place of **new**, you can define this macro in your source files:
85
+
If you don't want to rewrite your entire program to use `DEBUG_NEW` in place of **new**, you can define this macro in your source files:
90
86
91
87
```cpp
92
88
#definenew DEBUG_NEW
93
89
```
94
90
95
91
When you do an [object dump](#BKMK_Taking_object_dumps), each object allocated with `DEBUG_NEW` will show the file and line number where it was allocated, allowing you to pinpoint the sources of memory leaks.
96
92
97
-
The Debug version of the MFC framework uses `DEBUG_NEW` automatically, but your code does not. If you want the benefits of `DEBUG_NEW`, you must use `DEBUG_NEW` explicitly or **#define new** as shown above.
98
-
99
-
[In this topic](#BKMK_In_this_topic)
93
+
The Debug version of the MFC framework uses `DEBUG_NEW` automatically, but your code doesn't. If you want the benefits of `DEBUG_NEW`, you must use `DEBUG_NEW` explicitly or **#define new** as shown above.
1. Create a [CMemoryState](/previous-versions/visualstudio/visual-studio-2010/2ads32e2(v=vs.100)) object and call the [CMemoryState::Checkpoint](/cpp/mfc/reference/cmemorystate-structure#checkpoint) member function. This creates the first memory snapshot.
129
121
130
122
2. After your program performs its memory allocation and deallocation operations, create another `CMemoryState` object and call `Checkpoint` for that object. This gets a second snapshot of memory usage.
131
123
132
-
3. Create a third `CMemoryState` object and call its [CMemoryState::Difference](/cpp/mfc/reference/cmemorystate-structure#difference) member function, supplying as arguments the two previous `CMemoryState` objects. If there is a difference between the two memory states, the `Difference` function returns a nonzero value. This indicates that some memory blocks have not been deallocated.
124
+
3. Create a third `CMemoryState` object and call its [CMemoryState::Difference](/cpp/mfc/reference/cmemorystate-structure#difference) member function, supplying as arguments the two previous `CMemoryState` objects. If there's a difference between the two memory states, the `Difference` function returns a nonzero value. This indicates that some memory blocks haven't been deallocated.
133
125
134
126
This example shows what the code looks like:
135
127
@@ -154,14 +146,12 @@ Before you can use the memory diagnostics facilities, you must enable diagnostic
154
146
#endif
155
147
```
156
148
157
-
Notice that the memory-checking statements are bracketed by **#ifdef _DEBUG / #endif** blocks so that they are compiled only in Debug versions of your program.
149
+
Notice that the memory-checking statements are bracketed by **#ifdef _DEBUG / #endif** blocks so that they're compiled only in Debug versions of your program.
158
150
159
151
Now that you know a memory leak exists, you can use another member function, [CMemoryState::DumpStatistics](/cpp/mfc/reference/cmemorystate-structure#dumpstatistics) that will help you locate it.
The [CMemoryState::Difference](/cpp/mfc/reference/cmemorystate-structure#difference) function looks at two memory-state objects and detects any objects not deallocated from the heap between the beginning and end states. After you have taken memory snapshots and compared them using `CMemoryState::Difference`, you can call [CMemoryState::DumpStatistics](/cpp/mfc/reference/cmemorystate-structure#dumpstatistics) to get information about the objects that have not been deallocated.
154
+
The [CMemoryState::Difference](/cpp/mfc/reference/cmemorystate-structure#difference) function looks at two memory-state objects and detects any objects not deallocated from the heap between the beginning and end states. After you have taken memory snapshots and compared them using `CMemoryState::Difference`, you can call [CMemoryState::DumpStatistics](/cpp/mfc/reference/cmemorystate-structure#dumpstatistics) to get information about the objects that haven't been deallocated.
165
155
166
156
Consider the following example:
167
157
@@ -193,16 +183,14 @@ Non-object blocks include arrays and structures allocated with `new`. In this ca
193
183
194
184
`Total allocations` gives the total amount of memory used by the program.
In an MFC program, you can use [CMemoryState::DumpAllObjectsSince](/cpp/mfc/reference/cmemorystate-structure#dumpallobjectssince) to dump a description of all objects on the heap that have not been deallocated. `DumpAllObjectsSince` dumps all objects allocated since the last [CMemoryState::Checkpoint](/cpp/mfc/reference/cmemorystate-structure#checkpoint). If no `Checkpoint` call has taken place, `DumpAllObjectsSince` dumps all objects and nonobjects currently in memory.
187
+
In an MFC program, you can use [CMemoryState::DumpAllObjectsSince](/cpp/mfc/reference/cmemorystate-structure#dumpallobjectssince) to dump a description of all objects on the heap that haven't been deallocated. `DumpAllObjectsSince` dumps all objects allocated since the last [CMemoryState::Checkpoint](/cpp/mfc/reference/cmemorystate-structure#checkpoint). If no `Checkpoint` call has taken place, `DumpAllObjectsSince` dumps all objects and nonobjects currently in memory.
200
188
201
189
> [!NOTE]
202
190
> Before you can use MFC object dumping, you must [enable diagnostic tracing](#BKMK_Enabling_memory_diagnostics).
203
191
204
192
> [!NOTE]
205
-
> MFC automatically dumps all leaked objects when your program exits, so you do not need to create code to dump objects at that point.
193
+
> MFC automatically dumps all leaked objects when your program exits, so you don't need to create code to dump objects at that point.
206
194
207
195
The following code tests for a memory leak by comparing two memory states and dumps all objects if a leak is detected.
208
196
@@ -239,8 +227,6 @@ You can set a breakpoint on a particular memory allocation by setting the global
239
227
240
228
The C run-time library has a similar function, [_CrtSetBreakAlloc](/cpp/c-runtime-library/reference/crtsetbreakalloc), that you can use for C run-time allocations.
@@ -266,15 +252,15 @@ CString s("This is a frame variable");
266
252
CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );
267
253
```
268
254
269
-
The `CPerson` constructor takes three arguments that are pointers to `char`, which are used to initialize `CString` member variables. In the memory dump, you can see the `CPerson` object along with three nonobject blocks (3, 4, and 5). These hold the characters for the `CString` member variables and will not be deleted when the `CPerson` object destructor is invoked.
255
+
The `CPerson` constructor takes three arguments that are pointers to `char`, which are used to initialize `CString` member variables. In the memory dump, you can see the `CPerson` object along with three nonobject blocks (3, 4, and 5). These hold the characters for the `CString` member variables and won't be deleted when the `CPerson` object destructor is invoked.
270
256
271
257
Block number 2 is the `CPerson` object itself. `$51A4` represents the address of the block and is followed by the contents of the object, which were output by `CPerson`::`Dump` when called by [DumpAllObjectsSince](/cpp/mfc/reference/cmemorystate-structure#dumpallobjectssince).
272
258
273
259
You can guess that block number 1 is associated with the `CString` frame variable because of its sequence number and size, which matches the number of characters in the frame `CString` variable. Variables allocated on the frame are automatically deallocated when the frame goes out of scope.
274
260
275
261
**Frame Variables**
276
262
277
-
In general, you should not worry about heap objects associated with frame variables because they are automatically deallocated when the frame variables go out of scope. To avoid clutter in your memory diagnostic dumps, you should position your calls to `Checkpoint` so that they are outside the scope of frame variables. For example, place scope brackets around the previous allocation code, as shown here:
263
+
In general, you shouldn't worry about heap objects associated with frame variables because they're automatically deallocated when the frame variables go out of scope. To avoid clutter in your memory diagnostic dumps, you should position your calls to `Checkpoint` so that they're outside the scope of frame variables. For example, place scope brackets around the previous allocation code, as shown here:
278
264
279
265
```cpp
280
266
oldMemState.Checkpoint();
@@ -308,7 +294,7 @@ Notice that some allocations are objects (such as `CPerson`) and some are nonobj
308
294
309
295
**Preventing Memory Leaks**
310
296
311
-
Notice in the code above that the memory block associated with the `CString` frame variable has been deallocated automatically and does not show up as a memory leak. The automatic deallocation associated with scoping rules takes care of most memory leaks associated with frame variables.
297
+
Notice in the code above that the memory block associated with the `CString` frame variable has been deallocated automatically and doesn't show up as a memory leak. The automatic deallocation associated with scoping rules takes care of most memory leaks associated with frame variables.
312
298
313
299
For objects allocated on the heap, however, you must explicitly delete the object to prevent a memory leak. To clean up the last memory leak in the previous example, delete the `CPerson` object allocated on the heap, as follows:
314
300
@@ -322,8 +308,6 @@ For objects allocated on the heap, however, you must explicitly delete the objec
When you derive a class from [CObject](/cpp/mfc/reference/cobject-class), you can override the `Dump` member function to provide additional information when you use [DumpAllObjectsSince](/cpp/mfc/reference/cmemorystate-structure#dumpallobjectssince) to dump objects to the [Output window](../ide/reference/output-window.md).
329
313
@@ -347,7 +331,7 @@ public:
347
331
};
348
332
```
349
333
350
-
Because object dumping only makes sense when you are debugging your program, the declaration of the `Dump` function is bracketed with an **#ifdef _DEBUG / #endif** block.
334
+
Because object dumping only makes sense when you're debugging your program, the declaration of the `Dump` function is bracketed with an **#ifdef _DEBUG / #endif** block.
351
335
352
336
In the following example, the `Dump` function first calls the `Dump` function for its base class. It then writes a short description of each member variable along with the member's value to the diagnostic stream.
353
337
@@ -377,8 +361,6 @@ pMyPerson->Dump( afxDump );
377
361
#endif
378
362
```
379
363
380
-
[In this topic](#BKMK_In_this_topic)
381
-
382
364
## <aname="BKMK_Reducing_the_size_of_an_MFC_Debug_build"></a> Reducing the size of an MFC Debug build
383
365
The debug information for a large MFC application can take up a lot of disk space. You can use one of these procedures to reduce the size:
384
366
@@ -425,7 +407,7 @@ Building selected modules with the MFC debug libraries enables you to use steppi
425
407
426
408
6. Click **OK** to save the new build options and close the **Property Pages** dialog box.
427
409
428
-
5. From the **Build** menu, select **Rebuild**. This removes all debug information from your modules but does not affect the MFC library.
410
+
5. From the **Build** menu, select **Rebuild**. This removes all debug information from your modules but doesn't affect the MFC library.
429
411
430
412
6. Now you must add debug information back to selected modules in your application. Remember that you can set breakpoints and perform other debugger functions only in modules you have compiled with debug information. For each project file in which you want to include debug information, carry out the following steps:
431
413
@@ -441,13 +423,11 @@ Building selected modules with the MFC debug libraries enables you to use steppi
441
423
442
424
6. Click the **Debug Information Format** settings and select the desired option (usually **/ZI**) for debug information.
443
425
444
-
7. If you are using an application wizard-generated application or have precompiled headers, you have to turn off the precompiled headers or recompile them before compiling the other modules. Otherwise, you will receive warning C4650 and error message C2855. You can turn off precompiled headers by changing the **Create/Use Precompiled Headers** setting in the **\<Project> Properties** dialog box (**Configuration Properties** folder, **C/C++** subfolder, **Precompiled Headers** category).
426
+
7. If you're using an application wizard-generated application or have precompiled headers, you have to turn off the precompiled headers or recompile them before compiling the other modules. Otherwise, you will receive warning C4650 and error message C2855. You can turn off precompiled headers by changing the **Create/Use Precompiled Headers** setting in the **\<Project> Properties** dialog box (**Configuration Properties** folder, **C/C++** subfolder, **Precompiled Headers** category).
445
427
446
428
7. From the **Build** menu, select **Build** to rebuild project files that are out of date.
447
429
448
430
As an alternative to the technique described in this topic, you can use an external makefile to define individual options for each file. In that case, to link with the MFC debug libraries, you must define the [_DEBUG](/cpp/c-runtime-library/debug) flag for each module. If you want to use MFC release libraries, you must define NDEBUG. For more information on writing external makefiles, see the [NMAKE Reference](/cpp/build/running-nmake).
0 commit comments