根据Linux程序员手册:
brk()和sbrk()更改了程序中断的位置,这定义了进程数据段的结束。
数据段在这里意味着什么?是数据段还是数据、BSS和堆的组合?
根据wiki的说法:
有时,数据、BSS和堆区域统称为“数据段”。
我认为没有理由改变数据段的大小。如果是数据、BSS和堆,那么它就有意义了,因为堆将获得更多的空间。
这就引出了我的第二个问题。在我读过的所有文章中,作者说堆向上增长,堆栈向下增加。但是他们没有解释的是,当堆占据堆和堆栈之间的所有空间时会发生什么?

发布于 2018-03-26 08:50:32

“中断”---被操纵的地址brk和sbrk。你读过的文档将此描述为“数据段”的结尾,因为在传统的(预共享库,预共享库)中-mmap)Unix数据段与堆是连续的;在程序启动之前,内核将从地址零开始将“text”和“data”块加载到RAM中(实际上略高于地址零,因此空指针真正没有指向任何内容),并将中断地址设置为数据段的末尾。第一次呼叫malloc然后使用sbrk要移动拆分并创建堆,请执行以下操作介于两者之间数据段的顶部和新的、更高的中断地址,如图所示,以及随后使用的malloc会在必要的时候用它来使堆变大。
同时,堆栈从内存的顶部开始并向下扩展。堆栈不需要显式的系统调用来使其更大;要么它开始时分配给它的RAM尽可能多(这是传统的方法),要么堆栈下面有一个预留地址区域,当内核注意到试图在堆栈上写入内存时,它会自动分配RAM(这是现代的方法)。无论哪种方式,在地址空间的底部都可能有一个“保护”区域,可以用于堆栈。如果存在此区域(所有现代系统都这样做),则永久取消映射;如果任一堆栈或堆试图发展为它,将得到一个分段错误。但是,传统上内核并不试图强制执行边界;堆栈可以发展为堆,堆也可以发展为堆栈,不管是哪种方式,它们都会在彼此的数据上乱涂乱写,程序就会崩溃。如果你很幸运的话,它会立即坠毁。
我不知道这个图表中的512 GB是从哪里来的。它意味着64位虚拟地址空间,这与您在那里的非常简单的内存映射不一致。一个真正的64位地址空间看起来更像这样:

这不是远程扩展的,也不应该被解释为任何给定的操作系统都是如何工作的(在我绘制了它之后,我发现Linux实际上使可执行文件的地址比我想象的接近零,并且共享库的地址高得惊人)。此图的黑色区域未映射--任何访问都会导致立即分段错误--它们是巨相对于灰色区域。浅灰区域是程序及其共享库(可以有几十个共享库);每个库都有一个独立文本和数据段(和“bss”段,它也包含全局数据,但是初始化为所有位-零,而不是占用磁盘上的可执行文件或库中的空间)。堆不再一定是连续的可执行文件的数据段--我是这样画的,但是看起来至少Linux不这样做。堆栈不再与虚拟地址空间的顶部挂钩,堆与堆栈之间的距离非常大,因此不必担心跨越它。
中断仍然是堆的上限。然而,我没有显示的是,在黑色的某个地方,可能会有几十个独立的内存分配,是用mmap而不是brk。(操作系统将试图使这些远离brk使它们不会碰撞。)
发布于 2018-03-26 10:03:37
最小可运行示例
BRK()系统调用做什么?
请求内核允许读写一个称为堆的连续内存块。
如果你不问的话,这可能会让你受伤。
无brk:
#define _GNU_SOURCE
#include <unistd.h>
int main(void) {
/* Get the first address beyond the end of the heap. */
void *b = sbrk(0);
int *p = (int *)b;
/* May segfault because it is outside of the heap. */
*p = 1;
return 0;
}带着brk:
#define _GNU_SOURCE
#include <assert.h>
#include <unistd.h>
int main(void) {
void *b = sbrk(0);
int *p = (int *)b;
/* Move it 2 ints forward */
brk(p + 2);
/* Use the ints. */
*p = 1;
*(p + 1) = 2;
assert(*p == 1);
assert(*(p + 1) == 2);
/* Deallocate back. */
brk(b);
return 0;
}在Ubuntu 14.04上测试。
虚拟地址空间可视化
以前brk:
+------+ <-- Heap Start == Heap End后brk(p + 2):
+------+ <-- Heap Start + 2 * sizof(int) == Heap End
| |
| You can now write your ints
| in this memory area.
| |
+------+ <-- Heap Start后brk(b):
+------+ <-- Heap Start == Heap Endhttps://stackoverflow.com/questions/-100003687
复制相似问题