问题描述
我很难理解sbrk()
和mmap()
以及munmap()
。
这与How do I free memory obtained by sbrk()?密切相关,但是我还有更多问题。
如果我有以下程序:
int main(void) {
void* first = sbrk(4096);
void* second = sbrk(4096);
return 0;
}
据我了解,sbrk()
将通过传入的值来增加堆的大小,然后返回一个指向该内存段开头的指针。
例如,如果当前堆中断(堆结束)为0x1000,而我调用void* first = sbrk(4096)
,则堆中断将为0x2000,返回的指针将为0x1000。
所以我假设然后,当我调用void* second = sbrk(4096)
时,堆中断将在0x3000处,并且返回的指针将在0x2000处?
关于释放此内存,我知道如果再次调用sbrk()
,我认为sbrk(-4096)将释放堆内存。但是那不是免费的void* second
,如果我想免费的void* first
会发生什么?
我还可以使用munmap取消映射sbrk()
中分配的内存吗?因此,调用诸如munmap(second,4096);
之类的东西还是仅当我使用mmap()
来分配内存时才可以使用?
谢谢,胡安
请注意,这是给大学分配的,我只使用malloc和free,但是分配是重新实现malloc。
解决方法
所以我假设然后,当我调用void * second = sbrk(4096)时,堆中断将位于0x3000,返回的指针将为0x2000?
是的
关于释放此内存,我知道如果再次调用sbrk(),我认为sbrk(-4096)将释放堆内存。但是那不是免费的空虚*,
它将“释放第二个”-释放4096个字节。
如果我想先释放void *,会发生什么?
您必须按顺序打电话给他们。
void *first = sbrk(4096);
void *second = sbrk(4096);
sbrk(-4096);
sbrk(-4096);
或仅sbrk(-4096 * 2);
。
我可以使用munmap从sbrk()取消分配内存的映射吗?
否。
所以叫munmap(second,4096);
否。
还是仅当我使用mmap()分配内存时才能使用?
是的
Sbrk移动指针并返回一个较旧的地址。过于简单的实现可能是这样的:
char heap_memory[1000000];
char *heap = heap_memory;
char *heap_end = heap + 1000000;
void *sbrk(int toadd) {
// check for out of memory
if (heap + toadd > heap_end) return NULL;
// increment heap and return the old address
char *old_address = heap;
heap += toadd;
return old_address;
}
只需在某个缓冲区内移动指针即可。 mmap
是一种不同的机制,它将您选择的内存地址映射到某些数据。您无法将sbrk
返回的值传递给mmap
。