我有以下代码
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)
虽然a
和b
都是char指针。为什么指向b
的指针等于a + 16
?偏移16个字节的原因是什么?
答案 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位)的因子。