在Debug 模式下,
VC 會把未初始化的棧內存全部填成0xcc,當字符串看就是 燙燙燙燙……
會把未初始化的堆內存全部填成0xcd,當字符串看就是 屯屯屯屯……
可以讓我們方便地看出那些內存沒初始化
但是Release 模式下不會有這種附加動作,原來那塊內存里是什么就是什么
名字 描述
0xCD Clean Memory 申請的內存由malloc或者new完成
0xDD Dead Memory 釋放后的內存,用來檢測懸垂指針
0xFD Fence Memory 動態申請后的內存值,沒有初始化。用來檢測數組的下標界限
0xAB (Allocated Block?) 使用LocalAlloc()分配的內存 0x0DF0ADBA Bad Food 使用LocalAlloc並且參數為LMEM_FIXED,但是還沒寫入
0xCC 使用了/GZ選項,沒有初始化的自動變量在DBGHEAP.C文件中,
Microsoft's memorymanagement functions often initialize memory with special values. The followingarticle describes frequent used variants.
Microsoft Visual C++ Runtime library
C runtime library provides it own debug codes:
0xCD, 0xCDCDCDCD - New objects. New objects are filled with 0xCD when they areallocated.
0xFD, 0xFDFDFDFD - No-man's land memory. Extra bytes that belong to theinternal block allocated, but not the block you requested. They are placedbefore and after requested blocks and used for data bound checking.
0xDD, 0xDDDDDDDD - Freed blocks. The freed blocks kept unused in the debugheap's linked list when the _CRTDBG_DELAY_FREE_MEM_DF flag is set are currentlyfilled with 0xDD. Although in some cases you won't see magic 0xDDDDDDDD value,as it will be overwritten by another debug function (e.g. 0xFEEEFEEE forHeapFree).
These constants are defined in DbgHeap.c file as
static unsigned char _bNoMansLandFill = 0xFD; /* fill no-man's land with this*/
static unsigned char _bDeadLandFill = 0xDD; /* fill free objects with this */
static unsigned char _bCleanLandFill = 0xCD; /* fill new objects with this */
Compiler initialisations
0xCC, 0xCCCCCCCC - The /GX Microsoft Visual C++ compiler option initialises alllocal variables not explicitly initialised by the program. It fills all memoryused by these variables with 0xCC, 0xCCCCCCCC.
Windows NT memory codes
0xABABABAB - Memory following a block allocated by LocalAlloc().
0xBAADF00D - "Bad Food". This is memory allocated via LocalAlloc(LMEM_FIXED, ... ). It is memory that has been allocated but not yet written to.
0xFEEEFEEE - OS fill heap memory, which was marked for usage, but wasn'tallocated by HeapAlloc() or LocalAlloc(). Or that memory just has been freed byHeapFree().
好了,現在來解釋一下標題。
未初始化的變量會被系統賦初值為0xCC,超過了ASCII碼0-127這個范圍,因此這個“字符串”被系統當成了寬字符組成的字符串,即兩個字節數據組成一個字符,而0xCCCC表示的寬字符正好是亂碼中的那個“燙”字。
燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙燙
是debug中未初始化的棧變量
屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯
是debug中未初始化的堆變量
舉個例子:
int main(void) { char x[4]; return 0; }
用斷點查看X的值,可以發現,“燙燙”出現了:
x 0x0012ff60 "燙燙燙燙?" char [4]
查看反匯編:
1: int main(void) 2: { 004113A0 55 push ebp 004113A1 8B EC mov ebp,esp 004113A3 81 EC CC 00 00 00 sub esp,0CCh 004113A9 53 push ebx 004113AA 56 push esi 004113AB 57 push edi 004113AC 8D BD 34 FF FF FF lea edi,[ebp-0CCh] 004113B2 B9 33 00 00 00 mov ecx,33h 004113B7 B8 CC CC CC CC mov eax,0CCCCCCCCh 004113BC F3 AB rep stos dword ptr es:[edi] 3: char x[4]; 4: return 0; 004113BE 33 C0 xor eax,eax 5: }
簡單解釋一下關鍵句的含義:
004113AC 8D BD 34 FF FF FF lea edi,[ebp-0CCh]
將獲得的0CCh大小的棧空間首地址賦給edi
004113B2 B9 33 00 00 00 mov ecx,33h
rep的循環次數為33h
004113B7 B8 CC CC CC CC mov eax,0CCCCCCCCh
eax = 0CCCCCCCCh
004113BC F3 AB rep stos dword ptr es:[edi]
將棧空間的33H個雙字節賦值為0CCCCCCCCh
而0xcccc用漢語表示剛好就是“燙”
oxcc正好是中斷int 3的指令 起到保護作用