1

我很难理解sbrk()mmap(),以及munmap()

这与如何释放 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。

4

1 回答 1

2

所以我假设当我调用 void* second = sbrk(4096) 时,堆中断将在 0x3000 并且返回的指针将是 0x2000?

是的。

说到释放这块内存,我知道如果你再次调用 sbrk(),我认为 sbrk(-4096) 会释放堆内存。但那不是第二个免费的 void* 吗?

它将“释放第二个”-释放 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是一种不同的机制,它将您选择的内存地址映射到某些数据。您不能传递sbrkto返回的值mmap

于 2020-08-19T07:31:41.893 回答