sbrk(0) 是否也会在后台分配内存?

Does sbrk(0) also allocate memory behind the scenes?

提问人:Shivanshu Arora 提问时间:10/22/2023 最后编辑:Shivanshu Arora 更新时间:10/22/2023 访问量:48

问:

我正在学习 sbrk、brk、mmap 等的工作原理以及它们提供的功能。我正在编写一个非常基本的代码,如下所示

int main(int argc, char* argv[]) {
void* f1 = sbrk(0);
  int* newarr = (int*)f1;
  for(int i=0;i<2048;i++) {
    newarr[i] = 1;
  }
  cout<<newarr[9]<<endl;
return 0;
}

在这种情况下,我只是简单地执行了 sbrk(0) 来找出当前的程序中断,但是,正如您所看到的,我也能够创建一个长度为 2048 甚至更大的 newarr 并使用它。这意味着我现在在堆上有内存,而没有实际移动程序中断。请注意,除了执行 sbrk(0) 之外,我没有执行任何其他 brk 或 sbrk 调用,所以我的猜测是堆现在是空的?

它是如何工作的?我的理解是,我必须将程序中断移动一些字节,并且我只能使用这些字节,否则这将是段错误。

编辑:我发现这个链接 https://iq.opengenus.org/mmap-brk-and-sbrk-in-unix/ 说第一次调用sbrk时分配了100k的默认空间,所以这一定是这种行为的原因吗?但是,如果我多次执行sbrk(0)并打印程序中断,则都是一样的

Linux 内存管理系统 调用

评论

0赞 stark 10/22/2023
查看 stackoverflow.com/q/19020504/1216776

答:

2赞 user22405329 10/22/2023 #1

操作系统只能以页为单位分配内存。例如,在 x86 上,页面大小为 4kiB(4096 字节),因此内核可以分配或不分配 4096 字节。此外,程序的数据段不太可能完全停在 4k 边界处 - 因此剩余空间将在那里,即使从技术上讲是在程序中断之后。MMU 保护只对整个页面有效,因此内核无法强制执行中断屏障。

这篇文章的说法似乎不正确。我已经查看了 sbrk 的 GLIBC 源代码,以及 brk 的源代码 - 我没有看到提到变量或 100k 默认值。内核中的代码只是执行页面对齐,然后调用 ._mneedmmap

评论

0赞 Shivanshu Arora 10/22/2023
我明白了,所以这基本上意味着即使我的代码有效,它也不会可靠,除非我实际移动程序中断并仅使用我移动程序中断的空间,对吗?
0赞 user22405329 10/22/2023
@ShivanshuArora 是的