为什么gcc在2次成功分配之间留下16个字节?

时间:2014-10-12 06:52:33

标签: c gcc

我有以下代码

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都是char指针。为什么指向b的指针等于a + 16?偏移16个字节的原因是什么?

2 个答案:

答案 0 :(得分:4)

要求Malloc返回与任何基本类型 1 充分对齐的内存。

在这种情况下,对齐似乎是在16字节边界上。这应该满足任何基本类型的对齐要求。


1 (引用自:ISO / IEC 9899:201x 7.22.3内存管理功能1)
该 如果分配成功,则返回指针,以便可以将其分配给 指向具有基本对齐要求的任何类型对象的指针,然后使用 在分配的空间中访问这样的对象或这些对象的数组(直到空间 明确解除分配。)

答案 1 :(得分:1)

this视频的前20分钟详细解释了原因。

据我所知,每个内存分配过程都会在内存中留下一个 trace ,其中包含一些额外的信息(比如,分配的内存长度,即将到来的分配的下一个可用空间,等等)。所以,假设你分配10个整数的长度(10 * 4字节= 40个字节),这取决于系统结构(无论是32位还是64位),系统总是分配至少+1(可能更多)一些系统)额外的指针大小字节,它指向要分配的下一个空闲空间。也就是说,你的malloc为40个字节,在32位系统上分配(至少)44个字节。

更具体;如果您对malloc (40)的分配返回1200的地址,则表示:

(1)你的数组将放在地址1200和地址之间。 1240

(2)并且数组的长度(或指向下一个可用空间的指针)写在(1200 - 4) = 1196地址中。

(3)因此,此malloc的总分配空间变为44个字节。

同样,malloc信息的跟踪长度对于32位系统可能是4个字节,对于64位系统可能是8个字节。在某些系统上,根据所写的信息,它可能更长;但可以肯定的是,它将是4(32位)和8(64位)的因子。