sbrk() 在 C++ 中如何工作?

问题描述 投票:0回答:5

在哪里可以详细了解

sbrk()

它到底是如何运作的?

在什么情况下我想用

sbrk()
来代替繁琐的
malloc()
new()

顺便说一句,

sbrk()
的扩展是什么?

c++ malloc sbrk
5个回答
11
投票

查看 brk/sbrk 的规范

该调用基本上要求操作系统通过将先前的“中断值”增加一定量来为应用程序分配更多内存。该数量(第一个参数)是您的应用程序获得的额外内存量。

大多数基本的 malloc 实现都基于 sbrk 系统调用构建,以获取它们分割和跟踪的内存块。 mmap 函数通常被认为是更好的选择(这就是为什么像 dlmalloc 这样的 malloc 都支持 #ifdef)。

至于“它是如何工作的”,最简单级别的 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;
}

现代操作系统会做更多的事情,例如将页面映射到地址空间并为分配的每个内存块添加跟踪信息。


3
投票

sbrk 已经过时了,现在您可以使用 mmap 将某些页面映射到 /dev/zero 之外。它当然不是您用来代替 malloc 和朋友的东西,它更多的是实现这些的一种方法。当然,它只存在于基于 posix 的操作系统上,这些操作系统关心对古代代码的向后兼容性。

如果您发现 Malloc 和 New 太麻烦,您应该考虑垃圾收集...但要注意,这会带来潜在的性能成本,因此您需要了解自己在做什么。


2
投票

您永远不想使用

sbrk
代替
malloc
free
。它是不可移植的,通常仅由标准 C 库的实现者或在它不可用的情况下使用。它在其手册页中描述得很好:

描述

brk() 设置结束 数据段到指定的值 end_data_segment,当该值为 合理,系统确实有 内存足够,但进程没有 超过其最大数据大小(请参阅 设置限制(2))。

sbrk() 增加程序的数据 空间增量字节。 sbrk() 不是 一个系统调用,它只是一个C库 包装纸。调用 sbrk() 并使用 增量为 0 可以用来求 程序中断的当前位置。

返回值

成功后,brk() 返回 零,sbrk() 返回一个指向 新区域的开始。出错时, 返回 -1,并且 errno 设置为 ENOMEM。

最后,

malloc
free
并不麻烦——它们是C中分配和释放内存的标准方法。即使你想实现自己的内存分配器,最好只使用
malloc
free
作为基础 - 一种常见的方法是使用
malloc
一次分配一个大块,并从中提供内存分配(这就是子分配器或池通常实现的)


关于名称

sbrk
(或其表弟
brk
)的由来,可能与堆的末尾由称为“break”的指针标记这一事实有关。堆在 BSS 段之后开始,通常朝堆栈方向增长。


2
投票

您已经标记了这个 C++,那么为什么您要使用“麻烦的”malloc() 而不是 new 呢?无论如何,我不确定 malloc 有何麻烦;在内部也许是这样,但你为什么要关心呢?如果您确实关心(例如出于确定性的原因),您可以分配一个大池并为该池实现您自己的分配器。当然,在 C++ 中,您可以重载 new 运算符来做到这一点。

sbrk 用于将 C 库粘合到底层系统的操作系统内存管理。因此,进行操作系统调用而不是使用 sbrk()。至于它如何工作,那是依赖于系统的。例如,如果您正在使用 Newlib C 库(通常在带有 GNU 编译器的“裸机”嵌入式系统上使用),您必须自己实现 sbrk,因此它在这些情况下如何工作取决于您,只要它实现了扩展堆或失败所需的行为。

正如您从链接中看到的,它没有做太多事情,并且直接使用会非常麻烦 - 您可能最终会将其包装在 malloc 和 new 在任何情况下提供的所有功能中。


0
投票

如果您想了解如何在 sbrk() 之上实现 malloc(),请查看

http://web.ics.purdue.edu/~cs354/labs/lab6/

这是一个练习通过那个。 但是,在现代系统上,您不应该触摸此界面。由于您调用 malloc 和 new 很麻烦,我怀疑您没有安全正确地在代码中使用 sbrk 所需的所有经验。

© www.soinside.com 2019 - 2024. All rights reserved.