在哪里可以详细了解 sbrk()
?
sbrk()
是如何工作的?
在什么情况下,我需要使用 sbrk()
而不是繁琐的 malloc()
和 new()
?
顺便问一下,sbrk()
的扩展是什么?
uintptr_t current_break; // Some global variable for your application.
// This would probably be properly tracked by the OS for the process
void *sbrk(intptr_t incr)
{
uintptr_t old_break = current_break;
current_break += incr;
return (void*) old_break;
}
sbrk已经过时了,现在你可以使用mmap来从/dev/zero映射一些页面。它肯定不是你使用malloc和相关函数的替代品,而更多地是用于实现它们的一种方式。当然,它仅存在于关心向后兼容古老代码的基于posix的操作系统中。
如果你觉得Malloc和New太麻烦,你应该考虑使用垃圾回收...但要注意,这可能会带来性能成本,所以你需要了解自己在做什么。
sbrk
来替代 malloc
或者 free
。它是非可移植的,通常只由标准 C 库的实现者或者在没有其他选择时才使用。你可以在其 man page 上找到详细的描述。
描述
brk()将数据段结束位置设置为end_data_segment指定的值,当该值是合理的、系统具有足够的内存并且进程未超过其最大数据大小(参见setrlimit(2))时。
sbrk()通过increment参数增加程序的数据空间。sbrk()不是一个系统调用,它只是一个C库包装器。使用0作为increment参数调用sbrk()可以查找程序断点的当前位置。
返回值成功时,brk()返回0,sbrk()返回指向新区域开头的指针。失败时返回-1,并将errno设置为ENOMEM。
最后,malloc
和free
并不繁琐 - 它们是在C语言中分配和释放内存的标准方式。即使您想要实现自己的内存分配器,最好也只使用malloc
和free
作为基础 - 通常的方法是使用malloc
一次性分配大块内存,并从中提供内存分配(这就是子分配器或池通常实现的内容)。
你已经标记了这是C++,那么为什么要使用“繁琐”的malloc()而不是new呢?我不确定malloc有什么繁琐的地方;也许在内部有,但你为什么要关心呢?如果你确实关心(例如出于确定性的原因),你可以分配一个大的池子并为该池子实现自己的分配器。当然,在C++中,你可以重载new运算符来实现。
sbrk用于将C库与底层系统的OS内存管理粘合在一起。所以要进行OS调用,而不是使用sbrk()。至于它如何工作,那就取决于系统。例如,如果你正在使用Newlib C库(通常在使用GNU编译器的“裸机”嵌入式系统上使用),你必须自己实现sbrk,因此在这些情况下它的工作方式取决于你,只要它实现了扩展堆或失败的所需行为即可。
正如你从链接中看到的,它并没有做太多的事情,直接使用它会非常繁琐 - 你最终可能会将其包装在malloc和new提供的所有功能中。
这取决于您所说的malloc是否“繁琐”。现在通常不直接使用sbrk,除非您正在实现自己的内存分配器:例如,重载“new”运算符。即使如此,我可能也会使用malloc来提供初始内存。
如果您想了解如何在sbrk上实现malloc(),请查看http://web.ics.purdue.edu/~cs354/labs/lab6/,这是一个演示练习。
在现代系统上,您不应该触及此接口。由于您认为malloc和new很繁琐,我怀疑您没有足够的经验来安全、正确地使用sbrk编写代码。