2014-10-12 29 views
0

我有以下代碼爲什麼gcc在2次成功分配之間留下16個字節?

void foo() 
{ 
     char *a, *b; 
     int *c, *d; 
     a = (char*)malloc(1); 
     b = (char*)malloc(1); 
     c = (int*)malloc(4); 
     d = (int*)malloc(4); 
     *a = 10; 
     *b = 20; 
     *c = 30; 
     *d = 40; 
} 

下面是GDB輸出:

13  a = (char*)malloc(1); 
(gdb) n 
14  b = (char*)malloc(1); 
(gdb) n 
15  c = (int*)malloc(4); 
(gdb) n 
16  d = (int*)malloc(4); 
(gdb) n 
17  *a = 10; 
(gdb) n 
18  *b = 20; 
(gdb) n 
19  *c = 30; 
(gdb) n 
20  *d = 40; 
(gdb) n 
21 } 
(gdb) p a 
$1 = 0x804b008 "\n" 
(gdb) p b 
$2 = 0x804b018 "\024" 
(gdb) x/40b a 
0x804b008: 10 0 0 0 0 0 0 0 
0x804b010: 0 0 0 0 17 0 0 0 
0x804b018: 20 0 0 0 0 0 0 0 
0x804b020: 0 0 0 0 17 0 0 0 
0x804b028: 30 0 0 0 0 0 0 0 
(gdb) 

雖然ab都是字符指針。爲什麼指向b的指針等於a + 16?任何抵消16字節的原因?

+6

這是必要的,因爲每個分配必須足夠好地對齊以用於任何用途。另外,通常會在控制信息附近提供給您的指針,該信息描述了傳遞的數據段。最後,請注意,這是由'malloc()'的C庫實現控制的,而不是由C編譯器本身控制。當然,這兩者密切相關。 – 2014-10-12 06:58:50

+3

您不應該使用'malloc()'的返回值。請參閱http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – pmg 2014-10-12 08:30:03

+0

@Parth Shah系統上的sizeof(int *)是什麼? – 2501 2014-10-12 10:53:14

回答

4

Malloc需要返回足夠對齊任何基本類型的內存。

在你的情況下,對齊似乎是在16字節的邊界。這應該滿足任何基本類型的對齊要求。


(:ISO/IEC 9899:引自201X 7.22.3存儲器管理功能1)
的 指針返回,如果分配成功被適當地對準,使得它可以被分配給一個 指向具有基本對齊要求的任何類型對象的指針,然後使用 在分配的空間中訪問此類對象或此類對象的數組(直到明確釋放空間 )。

1

this視頻的前20分鐘詳細解釋了原因。

據我所知,每一個內存分配過程中留下一絲,其中包括一些額外的信息存儲器(如,內存分配的長度,爲即將到來的分配下一個可用的空間,等等)。因此,假設您分配了10個整數(10 * 4個字節= 40個字節)的長度,則取決於系統結構(無論是32位還是64位),系統始終分配至少+1(也許更多一些系統)額外指針大小字節,它指向下一個可用空間分配。也就是說,您的malloc爲40個字節,在32位系統上分配(至少)44個字節。

更具體地說;如果您對malloc (40)分配返回1200的地址,則這意味着:

(1)的陣列將所述地址之間鋪設1200 & 1240

(2)和所述陣列的長度(或指向下一個可用空間的指針)寫入地址(1200 - 4) = 1196

(3)因此,此malloc的總分配空間變爲44個字節。

此外,對於32位系統,malloc信息的跟蹤長度可以是4個字節,對於64位系統可以是8個字節。在某些系統上,根據所寫的信息,它可能會更長;但肯定的是,它將成爲4(32位)和8(64位)的因子。

相關問題