内存分配的间隔
Interval of memory allocation
struct Thing
{
int member1;
int member2;
};
struct Thing* heap()
{
struct Thing* heap_thing = (struct Thing*)malloc(sizeof(struct Thing));
heap_thing->member1 = 1;
heap_thing->member2 = 2;
printf("%p, %p, %p\n", heap_thing, &(heap_thing->member1), &(heap_thing->member2));
return heap_thing;
}
int main(int argc, char* argv[])
{
struct Thing* ptr = 0;
for (int i = 0; i < 5; ++i)
{
ptr = heap();
free(ptr);
}
return 0;
}
我希望打印的内存地址类似于:
(因为struct Thing
是8个字节)
0x000008, 0x000008, 0x00000c
0x000010, 0x000010, 0x000014
0x000018, 0x000018, 0x00001c ......
但是我屏幕上显示的是:
0x000008, 0x000008, 0x00000c
0x000018, 0x000018, 0x00001c
0x000028, 0x000028, 0x00002c ......
为什么 struct Thing
成员的内存地址没有按我的预期分配? ptr
之间的内存地址有16字节间隔但不是8字节?
大多数内存分配器都不是无开销的——在每个分配的块之后 and/or 之前的分配器内部使用了一些额外的内存。
在您系统的内存分配器中,这种开销似乎是每个分配块八个字节。这对于 32 位系统来说非常典型;它可能存储分配块的大小(4 字节)和指向前一个块的指针(4 字节),或类似的东西。
另一个要记住的因素是许多分配器都有最小分配量——也就是说,每个分配块的 "real" 大小都向上舍入到最接近标准大小的倍数。这是因为某些 CPU 特性(尤其是向量运算)通常需要内存与特定边界对齐,而且非常小的块难以跟踪。但是,在您的系统上,量程可能是八个字节,因此这在您的示例中没有发挥作用。 (您可以通过将结构中的一个成员从 int
更改为 char
来证明这种效果。)
struct Thing
{
int member1;
int member2;
};
struct Thing* heap()
{
struct Thing* heap_thing = (struct Thing*)malloc(sizeof(struct Thing));
heap_thing->member1 = 1;
heap_thing->member2 = 2;
printf("%p, %p, %p\n", heap_thing, &(heap_thing->member1), &(heap_thing->member2));
return heap_thing;
}
int main(int argc, char* argv[])
{
struct Thing* ptr = 0;
for (int i = 0; i < 5; ++i)
{
ptr = heap();
free(ptr);
}
return 0;
}
我希望打印的内存地址类似于:
(因为struct Thing
是8个字节)
0x000008, 0x000008, 0x00000c
0x000010, 0x000010, 0x000014
0x000018, 0x000018, 0x00001c ......
但是我屏幕上显示的是:
0x000008, 0x000008, 0x00000c
0x000018, 0x000018, 0x00001c
0x000028, 0x000028, 0x00002c ......
为什么 struct Thing
成员的内存地址没有按我的预期分配? ptr
之间的内存地址有16字节间隔但不是8字节?
大多数内存分配器都不是无开销的——在每个分配的块之后 and/or 之前的分配器内部使用了一些额外的内存。
在您系统的内存分配器中,这种开销似乎是每个分配块八个字节。这对于 32 位系统来说非常典型;它可能存储分配块的大小(4 字节)和指向前一个块的指针(4 字节),或类似的东西。
另一个要记住的因素是许多分配器都有最小分配量——也就是说,每个分配块的 "real" 大小都向上舍入到最接近标准大小的倍数。这是因为某些 CPU 特性(尤其是向量运算)通常需要内存与特定边界对齐,而且非常小的块难以跟踪。但是,在您的系统上,量程可能是八个字节,因此这在您的示例中没有发挥作用。 (您可以通过将结构中的一个成员从 int
更改为 char
来证明这种效果。)