記憶體的一些magic number和debug crt(0xCCCCCCCC和0xCDCDCDCD,debug版本的CRT為了方便除錯程式的初始值)

findumars發表於2019-03-21

除錯過debug版本的vc程式的人一定對0xCCCCCCCC和0xCDCDCDCD這樣的記憶體很有印象。這是debug版本的CRT為了方便除錯程式,在分配出來還沒有初始化的時候提供的初始值。

實際上,Windows上面還有更多這樣的初始值,見下表:

Uninitialized

 

BAADF00D

Used by Microsoft's LocalAlloc/GlobalAlloc/HeapAlloc(LMEM_FIXED) to mark uninitialised allocated heap memory

CCCCCCCC

Used by Microsoft's C++ debugging runtime library to mark uninitialised stack memory

CDCDCDCD

Used by Microsoft's C++ debugging runtime library to mark uninitialised heap memory

 

 

Freed

 

FEEEFEEE

Used by Microsoft's LocalFree/GlobalFree/HeapFree() to mark freed heap memory

DDDDDDDD

Used by MicroQuill's SmartHeap and Microsoft's C++ debugging heap to mark freed heap memory

 

 

No man's land

 

ABABABAB

Used by Microsoft's LocalAlloc/GlobalAlloc/HeapAlloc() to mark "no man's land" guard bytes after allocated heap memory

FDFDFDFD

Used by Microsoft's C++ debugging heap to mark "no man's land" guard bytes before and after allocated heap memory

表格來源:http://en.wikipedia.org/wiki/Magic_number_(programming)

除了debug CRT會幫你新增這些初始化值之外,微軟的堆管理函式也會在分配和釋放的時候新增一些初始化值。

LocalAlloc/GlobalAlloc,如果指定的是LMEM_FIXED(預設就指定了這個),並且沒有指定LMEM_ZEROINIT,則分配的記憶體中初始化值為BAADF00D(可以理解成badfood,也就是不能直接吃的意思,呵呵)。呼叫LocalFree/GlobalFree則其值會變為FEEEFEEE)可以理解成Free)。

HeapAlloc只要沒有指定HEAP_ZERO_MEMORY,也是一樣初始化值是BAADF00D,HeapFree之後則是FEEEFEEE。

另外,windows的三個heap分配函式(LocalAlloc/GlobalAlloc/HeapAlloc)分配記憶體的時候,會在分配的記憶體後面另外新增8個byte的Guard資料,也就是上表中的No man's land。其數值為ABABABAB

 

關於windows的heap管理函式,還有以下兩點需要注意:

  1. 如果分配的記憶體過大(比如幾十M,HeapAlloc會轉換成用VirtualAlloc來分配,而不是從堆上進行分配,所以分配和釋放之後的記憶體值不是上表所示。
  2. 開啟pageheap之後,呼叫HeapAlloc分配的初始化值為0xc0c0c0c0。HeapFree之後的記憶體則無法訪問

 

如果你的記憶體管理用的是new(malloc)和delete(free)這樣的CRT函式,那麼情況會更復雜一些。這些CRT記憶體管理函式是建立在上面的windows heap管理函式之上的。

尤其是debug版本的CRT,會做更多的事情,詳細見http://www.nobugs.org/developer/win32/debug_crt_heap.html

這裡簡要說明一下,new(malloc)分配的未初始化記憶體的值為CDCDCDCD,delete(free)之後的未初始化值為DDDDDDDD。

另外 ,debug CRT也有跟windows 的 heap管理函式一樣的No man's land資料,他們是FDFDFDFD(可以理解成fence),總共8個bytes,4個byte在payload前面 ,4個byte在payload後面。
需要注意的是CRT的管理資料實際上也是windows的heap管理函式的payload,所以當我們用CRT的函式來分配記憶體時,比如說10bytes,CRT向windows的heap管理函式會需要申請額外的記憶體(大概是40byte,也就是說總共50byte)。這額外的記憶體是CRT用來管理CRT記憶體的,其中就包括No man's land資料,另外還有分配了多少記憶體,記憶體型別,呼叫分配函式時的檔名和行數等等。詳細這40bytes作和作用請參見上面的URL

 

這裡還有一些關於Debug CRT的更詳細的介紹:http://www.codeguru.com/cpp/w-p/win32/tutorials/article.php/c9535/Inside-CRT-Debug-Heap-Management.htm

 

值得注意的是,以上是Debug CRT才會有的操作,release版本的CRT是直接呼叫windows的heap manager函式,所以其表現跟使用者直接呼叫heap manager函式是一樣的

https://www.cnblogs.com/georgepei/archive/2012/07/02/2573292.html

相關文章