sbrk(0)也在幕后分配内存吗?

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

我正在学习 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 memory-management system-calls
1个回答
0
投票

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

文章的说法似乎并不正确。我查看了 sbrk 的 GLIBC 源代码,以及 brk 的源代码 - 我没有看到任何提及

_mneed
变量或 100k 默认值。 内核中的代码只是进行页面对齐,并调用
mmap

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