提问人:Shivanshu Arora 提问时间:10/22/2023 最后编辑:Shivanshu Arora 更新时间:10/22/2023 访问量:48
sbrk(0) 是否也会在后台分配内存?
Does sbrk(0) also allocate memory behind the scenes?
问:
我正在学习 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)并打印程序中断,则都是一样的
答:
2赞
user22405329
10/22/2023
#1
操作系统只能以页为单位分配内存。例如,在 x86 上,页面大小为 4kiB(4096 字节),因此内核可以分配或不分配 4096 字节。此外,程序的数据段不太可能完全停在 4k 边界处 - 因此剩余空间将在那里,即使从技术上讲是在程序中断之后。MMU 保护只对整个页面有效,因此内核无法强制执行中断屏障。
这篇文章的说法似乎不正确。我已经查看了 sbrk 的 GLIBC 源代码,以及 brk 的源代码 - 我没有看到提到变量或 100k 默认值。内核中的代码只是执行页面对齐,然后调用 ._mneed
mmap
评论
0赞
Shivanshu Arora
10/22/2023
我明白了,所以这基本上意味着即使我的代码有效,它也不会可靠,除非我实际移动程序中断并仅使用我移动程序中断的空间,对吗?
0赞
user22405329
10/22/2023
@ShivanshuArora 是的
评论