Skip to content

Commit 63ae800

Browse files
committed
link fixes and acrolinx edits
1 parent c7873a1 commit 63ae800

File tree

1 file changed

+14
-34
lines changed

1 file changed

+14
-34
lines changed

docs/debugger/mfc-debugging-techniques.md

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ ms.subservice: debug-diagnostics
2727
---
2828
# MFC Debugging Techniques
2929

30-
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.
3131

3232
## <a name="BKMK_AfxDebugBreak"></a> AfxDebugBreak
3333
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`.
4646

4747
Be sure to remove `AfxDebugBreak` statements when you create a release build or use `#ifdef _DEBUG` to surround them.
4848

49-
[In this topic](#BKMK_In_this_topic)
50-
5149
## <a name="BKMK_The_TRACE_macro"></a> The TRACE macro
5250
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.
5351

@@ -78,25 +76,21 @@ TRACE( _T("This is a test of the TRACE macro that uses a TCHAR string: %s %d\n")
7876

7977
For more information on the **TRACE** macro, see [Diagnostic Services](/cpp/mfc/reference/diagnostic-services).
8078

81-
[In this topic](#BKMK_In_this_topic)
82-
8379
## <a name="BKMK_Memory_leak_detection_in_MFC"></a> Detecting memory leaks in MFC
8480
MFC provides classes and functions for detecting memory that is allocated but never deallocated.
8581

8682
### <a name="BKMK_Tracking_memory_allocations"></a> Tracking memory allocations
8783
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.
8884

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:
9086

9187
```cpp
9288
#define new DEBUG_NEW
9389
```
9490
9591
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.
9692
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.
10094
10195
### <a name="BKMK_Enabling_memory_diagnostics"></a> Enabling memory diagnostics
10296
Before you can use the memory diagnostics facilities, you must enable diagnostic tracing.
@@ -121,15 +115,13 @@ Before you can use the memory diagnostics facilities, you must enable diagnostic
121115
afxMemDF = allocMemDF | delayFreeMemDF | checkAlwaysMemDF;
122116
```
123117

124-
[In this topic](#BKMK_In_this_topic)
125-
126118
### <a name="BKMK_Taking_memory_snapshots"></a> Taking memory snapshots
127119

128120
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.
129121

130122
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.
131123

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.
133125

134126
This example shows what the code looks like:
135127

@@ -154,14 +146,12 @@ Before you can use the memory diagnostics facilities, you must enable diagnostic
154146
#endif
155147
```
156148

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.
158150

159151
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.
160152

161-
[In this topic](#BKMK_In_this_topic)
162-
163153
### <a name="BKMK_Viewing_memory_statistics"></a> Viewing memory statistics
164-
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.
165155

166156
Consider the following example:
167157

@@ -193,16 +183,14 @@ Non-object blocks include arrays and structures allocated with `new`. In this ca
193183

194184
`Total allocations` gives the total amount of memory used by the program.
195185

196-
[In this topic](#BKMK_In_this_topic)
197-
198186
### <a name="BKMK_Taking_object_dumps"></a> Taking object dumps
199-
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.
200188

201189
> [!NOTE]
202190
> Before you can use MFC object dumping, you must [enable diagnostic tracing](#BKMK_Enabling_memory_diagnostics).
203191
204192
> [!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.
206194
207195
The following code tests for a memory leak by comparing two memory states and dumps all objects if a leak is detected.
208196

@@ -239,8 +227,6 @@ You can set a breakpoint on a particular memory allocation by setting the global
239227

240228
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.
241229

242-
[In this topic](#BKMK_In_this_topic)
243-
244230
#### <a name="BKMK_Interpreting_memory_dumps"></a> Interpreting memory dumps
245231
Look at this object dump in more detail:
246232

@@ -266,15 +252,15 @@ CString s("This is a frame variable");
266252
CPerson* p = new CPerson( "Smith", "Alan", "581-0215" );
267253
```
268254
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.
270256
271257
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).
272258
273259
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.
274260
275261
**Frame Variables**
276262
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:
278264
279265
```cpp
280266
oldMemState.Checkpoint();
@@ -308,7 +294,7 @@ Notice that some allocations are objects (such as `CPerson`) and some are nonobj
308294

309295
**Preventing Memory Leaks**
310296

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.
312298

313299
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:
314300

@@ -322,8 +308,6 @@ For objects allocated on the heap, however, you must explicitly delete the objec
322308
}
323309
```
324310

325-
[In this topic](#BKMK_In_this_topic)
326-
327311
#### <a name="BKMK_Customizing_object_dumps"></a> Customizing object dumps
328312
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).
329313

@@ -347,7 +331,7 @@ public:
347331
};
348332
```
349333

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.
351335

352336
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.
353337

@@ -377,8 +361,6 @@ pMyPerson->Dump( afxDump );
377361
#endif
378362
```
379363

380-
[In this topic](#BKMK_In_this_topic)
381-
382364
## <a name="BKMK_Reducing_the_size_of_an_MFC_Debug_build"></a> Reducing the size of an MFC Debug build
383365
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:
384366

@@ -425,7 +407,7 @@ Building selected modules with the MFC debug libraries enables you to use steppi
425407

426408
6. Click **OK** to save the new build options and close the **Property Pages** dialog box.
427409

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.
429411

430412
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:
431413

@@ -441,13 +423,11 @@ Building selected modules with the MFC debug libraries enables you to use steppi
441423

442424
6. Click the **Debug Information Format** settings and select the desired option (usually **/ZI**) for debug information.
443425

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).
445427

446428
7. From the **Build** menu, select **Build** to rebuild project files that are out of date.
447429

448430
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).
449431

450-
[In this topic](#BKMK_In_this_topic)
451-
452432
## Related content
453433
- [Debugging Native Code](../debugger/debugging-native-code.md)

0 commit comments

Comments
 (0)