Malloc( ) - 在新页面请求或重新循环先前分配的内存之间做出决定
Malloc( ) - Decision between a new page(s) request or re-cycling previously allocated memory
我对 'C' 比较陌生,这个疑惑已经困扰我好几天了。希望各位大侠前来解救!
我似乎无法理解 malloc( ) 如何以及何时决定回收以前分配的内存,现在从同一进程中释放,并请求 OS 新页面。你们能帮我理解底层机制吗?将不胜感激!
这是我的示例测试代码:
#include <stdio.h>
#include <stdlib.h>
int main(){
char *ptr;
int mem_size1, mem_size2;
printf("\nEnter the size (in bytes) for malloc: ");
scanf("%d", &mem_size1);
ptr = (char *)malloc(mem_size1);
if (ptr!=NULL){
printf("\nAllocated %d bytes at addr=%p\n\n", mem_size1, ptr);
}
free(ptr); //free-up the addresses for re-allocation
printf("\nAgain, enter the size (in bytes) for malloc: ");
scanf("%d", &mem_size2);
ptr = (char *)malloc(sizeof(char)*mem_size2);
if (ptr!=NULL){
//check if the memory address is being re-allocated
printf("\nAllocated %d bytes at addr=%p\n\n", mem_size2, ptr);
}
free(ptr); //free-up the addresses for re-allocation
return(0);
}
这是我的输出序列:
情况一:初始分配大小为 10 字节,重新分配大小为 24 字节
Enter the size (in bytes) for malloc: 10
Allocated 10 bytes at addr=9C7010
Again, enter the size (in bytes) for malloc: 24
Allocated 24 bytes at addr=9C7010 //Same address space is being reused
情况二:初始分配大小为10字节,重新分配大小为25字节
Enter the size (in bytes) for malloc: 10
Allocated 10 bytes at addr=23F6010
Again, enter the size (in bytes) for malloc: 25
Allocated 25 bytes at addr=23F6030 //Different address space
我使用的是 64 位 Linux OS,我的系统页面大小是 4096B。
所以,我不明白为什么即使重新分配请求仅超过字节。谢谢!
这取决于 malloc 实现,但其中一项技术涉及分配堆 space 并有一个指向堆顶部的指针。返回的内存必须是连续的,并且可以在需要时增加堆的大小。
来自this malloc implementation based on sbrk syscall
The OS reserves stack and heap space for processes and sbrk lets us
manipulate the heap. sbrk(0) returns a pointer to the current top of
the heap. sbrk(foo) increments the heap size by foo and returns a
pointer to the previous top of the heap.
如果你释放你的指针,你可能会在连续的 space 中间得到一个空闲的 space,在这种情况下,malloc 只是将 space 标记为空闲,然后在下一个分配中,malloc 找到下一个连续 space 大到足以容纳您要求的分配:
For our malloc, we’ll want to re-use free space if possible,
allocating space when we can’t re-use existing space. Given that we
have this linked list structure, checking if we have a free block and
returning it is straightforward. When we get a request of some size,
we iterate through our linked list to see if there’s a free block
that’s large enough.
If we don’t find a free block, we’ll have to request space from the OS
using sbrk and add our new block to the end of the linked list.
是否使用 malloc returns 对 malloc 的不同调用在堆中的相同地址有多个标准,并且在同一程序的不同执行过程中可能会有所不同。
1) the first malloc'd memory must be passed to free()
before the second call to malloc
2) (here the user has no control)
the algorithm used by the malloc function
can be implemented in several different ways.
-some will keep re-allocating from the same memory address as long as space is available
-some will cycle through a pre-allocated set of memory buffers
-some use a randomizer for where in memory to start allocating
-etc
一个细节,大多数 malloc 调用稍微过度分配。 IE。实际上分配的比实际要求的要多一些(不要依赖这个 'feature' 因为这样做会导致未定义的行为并且 can/will 会导致段错误事件。)
在 OP 案例中,我怀疑使用的 malloc 函数预先分配了 tables 要分配的区域。恰好 table 大小在 24 和 25
之间有一个突破
我对 'C' 比较陌生,这个疑惑已经困扰我好几天了。希望各位大侠前来解救!
我似乎无法理解 malloc( ) 如何以及何时决定回收以前分配的内存,现在从同一进程中释放,并请求 OS 新页面。你们能帮我理解底层机制吗?将不胜感激!
这是我的示例测试代码:
#include <stdio.h>
#include <stdlib.h>
int main(){
char *ptr;
int mem_size1, mem_size2;
printf("\nEnter the size (in bytes) for malloc: ");
scanf("%d", &mem_size1);
ptr = (char *)malloc(mem_size1);
if (ptr!=NULL){
printf("\nAllocated %d bytes at addr=%p\n\n", mem_size1, ptr);
}
free(ptr); //free-up the addresses for re-allocation
printf("\nAgain, enter the size (in bytes) for malloc: ");
scanf("%d", &mem_size2);
ptr = (char *)malloc(sizeof(char)*mem_size2);
if (ptr!=NULL){
//check if the memory address is being re-allocated
printf("\nAllocated %d bytes at addr=%p\n\n", mem_size2, ptr);
}
free(ptr); //free-up the addresses for re-allocation
return(0);
}
这是我的输出序列:
情况一:初始分配大小为 10 字节,重新分配大小为 24 字节
Enter the size (in bytes) for malloc: 10
Allocated 10 bytes at addr=9C7010
Again, enter the size (in bytes) for malloc: 24
Allocated 24 bytes at addr=9C7010 //Same address space is being reused
情况二:初始分配大小为10字节,重新分配大小为25字节
Enter the size (in bytes) for malloc: 10
Allocated 10 bytes at addr=23F6010
Again, enter the size (in bytes) for malloc: 25
Allocated 25 bytes at addr=23F6030 //Different address space
我使用的是 64 位 Linux OS,我的系统页面大小是 4096B。
所以,我不明白为什么即使重新分配请求仅超过字节。谢谢!
这取决于 malloc 实现,但其中一项技术涉及分配堆 space 并有一个指向堆顶部的指针。返回的内存必须是连续的,并且可以在需要时增加堆的大小。
来自this malloc implementation based on sbrk syscall
The OS reserves stack and heap space for processes and sbrk lets us manipulate the heap. sbrk(0) returns a pointer to the current top of the heap. sbrk(foo) increments the heap size by foo and returns a pointer to the previous top of the heap.
如果你释放你的指针,你可能会在连续的 space 中间得到一个空闲的 space,在这种情况下,malloc 只是将 space 标记为空闲,然后在下一个分配中,malloc 找到下一个连续 space 大到足以容纳您要求的分配:
For our malloc, we’ll want to re-use free space if possible, allocating space when we can’t re-use existing space. Given that we have this linked list structure, checking if we have a free block and returning it is straightforward. When we get a request of some size, we iterate through our linked list to see if there’s a free block that’s large enough.
If we don’t find a free block, we’ll have to request space from the OS using sbrk and add our new block to the end of the linked list.
是否使用 malloc returns 对 malloc 的不同调用在堆中的相同地址有多个标准,并且在同一程序的不同执行过程中可能会有所不同。
1) the first malloc'd memory must be passed to free()
before the second call to malloc
2) (here the user has no control)
the algorithm used by the malloc function
can be implemented in several different ways.
-some will keep re-allocating from the same memory address as long as space is available
-some will cycle through a pre-allocated set of memory buffers
-some use a randomizer for where in memory to start allocating
-etc
一个细节,大多数 malloc 调用稍微过度分配。 IE。实际上分配的比实际要求的要多一些(不要依赖这个 'feature' 因为这样做会导致未定义的行为并且 can/will 会导致段错误事件。)
在 OP 案例中,我怀疑使用的 malloc 函数预先分配了 tables 要分配的区域。恰好 table 大小在 24 和 25
之间有一个突破