【问题标题】:Sbrk and negative parametersbrk 和负参数
【发布时间】:2014-03-26 16:04:00
【问题描述】:

我在使用 sbrk 释放内存时遇到问题。我通过 sbrk 一个负值,但它不会减少堆的开始。这是代码

int main(int argc, char** argv) {
    void * a = sbrk(0);
    printf("%p\n",a);

    sbrk(2);
    sbrk(-1);
    a = sbrk(0);
    printf("%p\n",a);
}

这是示例输出:

0x10734f000

0x10734f002

我不明白为什么在 sbrk 减一后打印的值没有返回为 0x10734f001。

我不允许在这个程序中使用 malloc。这是使用 sbrk 的 malloc 和 free 的自定义实现

【问题讨论】:

  • 检查你的sbrk(-1)的返回值......也许你不被允许这样做......
  • 返回值与 sbrk(0) 的值相同。那么还有其他方法可以减少 sbrk 值吗?
  • 什么操作系统/硬件/等等? brk 是非常特定于平台的。 (在我的 linux/amd64 上按您的意愿工作)
  • @keltar 我在 mac os x 上的 netbeans 7 中编写它并使用 32 位架构编译
  • opensource.apple.com/source/Libc/Libc-825.40.1/emulated/brk.c 我不确定它是否是 i386(或其他)的实际代码,但您遇到的行为非常适合它。

标签: c malloc sbrk


【解决方案1】:

刚刚使用 MacOSX Mavericks 对其进行了测试,并且 sbrk() 的行为(几乎)与在 Linux 上相同,但有两个例外:

  • 我收到编译器警告: tst21.c:12:6: warning: 'sbrk' is deprecated [-Wdeprecated-declarations]
  • 似乎不可能使用负值将内存返还给操作系统(据我所知,这与几十年前在 SYSV4 上观察到的行为相同:释放由sbrk() 分配的内存不是'不可能)

【讨论】:

    【解决方案2】:

    可能是您使用的尺寸太小,以至于sbrk() 内部发生了某种形式的舍入。我永远不会期望这样的字节级精度,它更有可能以页面为单位工作(在典型的 Linux 系统上为 4 KB 左右)。

    另外,请注意手册说:

    避免使用 brk() 和 sbrk():malloc(3) 内存分配包是一种可移植且舒适的内存分配方式。

    malloc() 可能知道sbrk() 的任何限制并处理它们,它是首选的应用程序级接口。

    【讨论】:

    • 我在很多地方都见过它。这是一个stackoverflow.com/questions/2051994/…
    • @cthemc 谢谢!我也没有看到手册页提到的负增量。我已经编辑了。
    • 我必须为学校项目编写自己的 malloc。提示建议使用负参数,所以我不确定为什么我所拥有的不起作用>_
    • 你在哪个平台上?无论增量/减量对有多大,您的示例都适用于我(Linux)。您是否注意到 sbrk() 不会返回新的,而是返回以前的 brk
    • @mfro im on mac os x 编译为 32 位架构
    【解决方案3】:

    printf 使用 malloc 从而增加数据段大小

    【讨论】:

    • 我很确定 printf 不使用 malloc。它只是即时转换数据并将其输出到标准输出。
    【解决方案4】:

    在不使用 printf 的情况下尝试一下,并使用调试器打印出结果。它将正常工作,结果将符合预期。堆将按预期增加 2 并减少 -1。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-18
      • 2013-04-08
      • 1970-01-01
      • 2011-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多