sbrk() 在 C++ 中如何工作?
在哪里可以阅读有关 sbrk()
的详细信息?
它究竟是如何运作的?
在什么情况下我想使用 sbrk()
而不是繁琐的 malloc()
和 new()
?
顺便说一句,sbrk()
的扩展是什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
在哪里可以阅读有关 sbrk()
的详细信息?
它究竟是如何运作的?
在什么情况下我想使用 sbrk()
而不是繁琐的 malloc()
和 new()
?
顺便说一句,sbrk()
的扩展是什么?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(5)
您已经标记了这个 C++,那么为什么要使用“麻烦的”malloc() 而不是 new 呢?无论如何,我不确定 malloc 有何麻烦;在内部也许是这样,但你为什么要关心呢?如果您确实关心(例如出于确定性的原因),您可以分配一个大池并为该池实现您自己的分配器。当然,在 C++ 中,您可以重载 new 运算符来执行此操作。
sbrk 用于将 C 库粘合到底层系统的操作系统内存管理。因此,进行操作系统调用而不是使用 sbrk()。至于它如何工作,那是依赖于系统的。例如,如果您使用 Newlib C 库(通常在带有 GNU 编译器的“裸机”嵌入式系统上使用),则必须 自己实现 sbrk,因此它在这些情况下如何工作取决于您,只要它实现了扩展堆或失败所需的行为。
正如您从链接中看到的,它没有做太多事情,并且直接使用会非常麻烦 - 您可能最终会将其包装在 malloc 和 new 无论如何提供的所有功能中。
You've tagged this C++ so why would you use 'cumbersome' malloc() rather than new? I am not sure what is cumbersome about malloc in any case; internally maybe so, but why would you care? And if you did care (for reasons of determinism for example), you could allocate a large pool and implement your own allocator for that pool. In C++ of course you can overload the new operator to do that.
sbrk is used to glue the C library to the underlying system's OS memory management. So make OS calls rather than using sbrk(). As to how it works, that is system dependent. If for example you are using the Newlib C library (commonly used on 'bare-metal' embedded systems with the GNU compiler), you have to implement sbrk yourself, so how it works in those circumstances is up to you so long as it achieves its required behaviour of extending the heap or failing.
As you can see from the link, it does not do much and would be extremely cumbersome to use directly - you'd probably end-up wrapping it in all the functionality that malloc and new provide in any case.
这取决于您所说的 malloc“麻烦”是什么意思。 sbrk 通常不再直接使用,除非您正在实现自己的内存分配器:IE,运算符覆盖“new”。即使这样,我也可能会使用 malloc 来提供我的初始记忆。
如果您想了解如何在 sbrk() 之上实现 malloc(),请查看 http://web.ics.purdue.edu/~cs354/labs/lab6/ 这是一个练习。
不过,在现代系统上,您不应该触摸此界面。由于您调用 malloc 和 new 很麻烦,我怀疑您不具备在代码中安全、正确使用 sbrk 所需的所有经验。
This depends on what you mean by malloc being "Cumbersome". sbrk is typically not used directly anymore, unless you're implementing your own memory allocator: IE, operator overriding "new". Even then I'd possibly use malloc to give me my initial memory.
If you'd like to see how to to implement malloc() on top of sbrk(), check out http://web.ics.purdue.edu/~cs354/labs/lab6/ which is an exercise going through that.
On a modern system you shouldn't touch this interface, though. Since you're calling malloc and new cumbersome, I suspect you don't have all the requisite experience to safely and properly use sbrk for your code.
查看brk/sbrk 的规范。
该调用基本上要求操作系统通过将先前的“中断值”增加一定量来为应用程序分配更多内存。该数量(第一个参数)是您的应用程序获得的额外内存量。
大多数基本的 malloc 实现都建立在 sbrk 系统调用之上,以获取它们分割和跟踪的内存块。 mmap 函数通常被认为是更好的选择(这就是为什么像 dlmalloc 这样的 malloc 都支持 #ifdef)。
至于“它是如何工作的”,sbrk在其最简单的级别可能看起来像这样:
现代操作系统会做更多的事情,例如将页面映射到地址空间并为每个页面添加跟踪信息分配的内存块。
Have a look at the specification for brk/sbrk.
The call basically asks the OS to allocate some more memory for the application by incrementing the previous "break value" by a certain amount. This amount (the first parameter) is the amount of extra memory your application then gets.
Most rudimentary malloc implementations build upon the sbrk system call to get blocks of memory that they split up and track. The mmap function is generally accepted as a better choice (which is why mallocs like dlmalloc support both with an #ifdef).
As for "how it works", an sbrk at its most simplest level could look something like this:
Modern operating systems would do far more, such as map pages into the address space and add tracking information for each block of memory allocated.
sbrk 已经过时了,现在您可以使用 mmap 将某些页面映射到 /dev/zero 之外。它当然不是您用来代替 malloc 和朋友的东西,它更多的是实现这些的一种方法。当然,它只存在于基于 posix 的操作系统上,这些操作系统关心对古代代码的向后兼容性。
如果您发现 Malloc 和 New 太麻烦,您应该考虑垃圾收集...但要注意,这会带来潜在的性能成本,因此您需要了解自己在做什么。
sbrk is pretty much obsolete, these days you'd use mmap to map some pages out of /dev/zero. It certainly isn't something you use instead of malloc and friends, it's more a way of implementing those. Also, of course, it exists only on posix-based operating systems that care about backwards compatibility to ancient code.
If you find Malloc and New too cumbersome, you should look into garbage collection instead... but beware, there is a potential performance cost to that, so you need to understand what you are doing.
您永远不想使用
sbrk
代替malloc
或free
。它是不可移植的,通常仅由标准 C 库的实现者或在它不可用的情况下使用。它在手册页中描述得非常好:最后,
malloc
和free
并不麻烦 - 它们是 C 中分配和释放内存的标准方法。即使您想实现自己的内存分配器,最好只需使用malloc
和free
作为基础 - 一种常见的方法是使用malloc
一次分配一个大块,并从中提供内存分配(这就是子分配器或池通常实现的)关于名称
sbrk
(或其表兄弟brk
)的起源,它可能与以下事实有关:堆的末尾由称为“break”的指针标记。堆在 BSS 段之后开始,通常朝堆栈方向增长。You never want to use
sbrk
instead ofmalloc
orfree
. It is non-portable and is typically used only by implementers of the standard C library or in cases where it's not available. It's described pretty well in its man page:Finally,
malloc
andfree
are not cumbersome - they are the standard way to allocate and release memory in C. Even if you want to implement your own memory allocator, it's best to just usemalloc
andfree
as the basis - a common approach is to allocate a large chunk at a time withmalloc
and provide memory allocation from it (this is what suballocators, or pools, usually implement)Re the origin of the name
sbrk
(or its cousinbrk
), it may have something to do with the fact that the end of the heap is marked by a pointer known as the "break". The heap starts right after the BSS segments and typically grows up towards the stack.