free如何知道釋放內存長度:vs與glibc分配內存時編譯器內部處理

鑑於網上這個資料實在太少,將之前整理過卻未徹底的一篇文章貼出來,但願大牛指正vs下內存管理方式。可聯繫gaoshiqiang1987@163.com函數

  • vs分配內存
vs沒有源碼,編譯器在分配內存時,分配給用戶的地址減去16個字節( 注1),保存了分配內存的類型與大小
以下表示了vs編譯器在分配內存時編譯器的處理,代碼以下:
 1 int _tmain(int argc, _TCHAR* argv[])
 2 {
 3     char *pcMem = (char *)malloc(8);
 4     short *psMem = (short *)malloc(12);
 5     int *piMem = (int *)malloc(16);
 6     long *plMem = (long *)malloc(20);
 7     float *pfMem  = (float*)malloc(32);
 8     double *pdMem = (double*)malloc(48);
 9 
10     system("PAUSE");
11     return 0;
12 }
vs2008本地斷點調試運行,對應地址分配以下
pcMem    0x007722c8 "屯屯屯屯鉿鉿"    char *
psMem    0x00772310    short *
piMem    0x00772358    int *
plMem    0x007723a8    long *
pfMem    0x00779230    float *
pdMem    0x00779290    double *
以下爲pChar減去16個字節的地址內容
0x007722B8  08 00 00 00 01 00 00 00 7a 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd fd fd fd fd ab ab ab ab
0x00772300  0c 00 00 00 01 00 00 00 7b 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd fd fd fd fd
0x00772348  10 00 00 00 01 00 00 00 7c 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
0x00772398  14 00 00 00 01 00 00 00 7d 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
0x00779220  20 00 00 00 01 00 00 00 7e 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
0x00779280  30 00 00 00 01 00 00 00 7f 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
從上面能夠總結如下幾點:
【1】第一順序的四個字節表明分配內存大小,並以小端(可能跟cpu有關,沒在大端機器上驗證,歡迎有大端機器的朋友驗證)方式呈現,在32位處理器或者32位操做系統下,程序所能容許分配最大內存爲2^32次冪;
【2】第二順序的四個字節不清楚表明什麼
【3】第三順序的四個字節表明分配數據類型( 注2
7a--char
7b--short
7c--int
7d--long
7e--float
7f--double

至於還有結構體以及類的分配可能須要另外討論this

【4】第四順序的四個字節都爲fd,猜想默認爲保留字節
對應不一樣結構體類型亦有不一樣值與之對應
疑問:如何從上面的資料計算申請分配內存的大小
咱們知道了所分配內存個數在第一順序的四個字節中有體現,可是所分配內存的單個單元大小几何單從第三順序的四個字節看不出因此然。再分析下第三順序的四個字節,對應【總結3】,略加分析,會發現單個單元大小也對應了某個值。我試了下不一樣結構體對應的值也各不同。猜想vs編譯器對其單個單元值在編譯時進行了計算,以便於在釋放內存時清楚該釋放內存大小。
 
  • glibc分配內存
glibc則清晰不少,由於能夠閱讀源碼,其在分配內存前增長了一個  HEADER_SIZE ,跟蹤malloc函數實現能夠發現
typedef struct header {
  long check;
  union {
    struct header *next;
    struct free_list *fl;
  } u;
} *header_t;
 
#define HEADER_SIZE sizeof (struct header)
 
typedef struct free_list {
 spin_lock_t lock; /* spin lock for mutual exclusion */
 header_t head; /* head of free list for this size */
#ifdef DEBUG
 int in_use; /* # mallocs - # frees */
#endif /* DEBUG */
} *free_list_t;

 

注1:這裏寫16byte是由於對比了分配內存首地址往前偏移8byte、16byte、32byte,發現16byte內存內容跟所分配的最接近,由於沒有源碼,因此只能作如上猜想spa

注2:沒有實際資料證實,只是猜測,上面幾個是基本數據類型,可是面對結構體或者類時其怎麼表示尚不清楚操作系統

相關文章
相關標籤/搜索