分配的内存地址取决于什么?

时间:2013-12-18 17:17:21

标签: c memory memory-management compiler-construction

查看这两个C代码:

char* char_pointer;
int* int_pointer;

char_pointer = (char*)malloc(5);
printf("location of char_pointer: %p\n", char_pointer);

int_pointer = (int*)malloc(10);
printf("location of int_pointer: %p\n", int_pointer);

free(char_pointer);

char_pointer = (char*)malloc(50);
printf("location of char_pointer: %p\n", char_pointer); 

char* char_pointer;
int* int_pointer;

char_pointer = (char*)malloc(200);
printf("location of char_pointer: %p\n", char_pointer);

int_pointer = (int*)malloc(10);
printf("location of int_pointer: %p\n", int_pointer);

free(char_pointer);

char_pointer = (char*)malloc(50);
printf("location of char_pointer: %p\n", char_pointer); 

输出结果为:

location of char_pointer: 0x23eb010
location of int_pointer: 0x23eb030
location of char_pointer: 0x23eb050

location of char_pointer: 0x1815010
location of int_pointer: 0x18150e0
location of char_pointer: 0x1815010

如您所见,在第一个程序中,它决定在char_pointer之后(在我释放和重新分配之后)分配int_pointer但在第二个程序中它决定分配char_pointer来代替释放记忆0x1815010

程序之间的唯一区别是分配和释放的内存量。

所以,我的问题是:

分配地点的决定取决于什么? (OS,编译器或硬件)

如果分配的内存量“很大”,为什么“它”决定分配代替释放的内存?

P.S。我在this book

中已经阅读过此问题

1 个答案:

答案 0 :(得分:4)

这取决于很多因素,并且没有简单的描述来描述行为。每个C运行时库都以不同方式实现malloc() - 如果您对它的工作原理感到好奇,您可以查看CRT的源代码。

以下是一些常用的malloc()实现:

大多数内存分配器工作的粗略方式是它们跟踪可用的内存区域。当一个请求进入分配内存时,他们会看到是否有一个至少与请求一样大的内存区域,如果是这样,就会分割内存,更新其内部数据结构以反映内存现在是分配,并返回相应的指针。如果没有足够的可用内存,分配器将要求操作系统提供更多虚拟内存地址空间(通常通过sbrk(2)mmap(2)VirtualAlloc)。

因此,如果块被分配然后被释放,然后经常(但不总是)请求相同大小(或更小)的另一个请求,则返回相同或类似的指针作为第一个块。

如果请求的分配非常大,分配器可能决定跳过其内部块处理,而是直接从OS满足请求 - 当分配数百KB或更多时,通常更直接{{1或者mmap()那个内存,而不是试图在内部空闲内存区域列表中找到一个空闲块。但并非所有分配器都这样做,而确切的转折点通常是可变的。

相关问题