学习c语言中的Brk系统调用

775 阅读3分钟

可以用brk()改变程序中断,它标志着进程的数据段的终止,即程序中断是未初始化的数据段完成后的第一个位置。增加程序分解允许内存给进程;减少分解允许内存给进程。当这个量是合理的,系统会有足够的内存,并且进程没有超过它的最大数据量,brk()将数据段的结束设置为addr提供的值。Brk()如果成功返回0。如果出现错误,则返回-1。系统函数brk()和sbrk()被用来调节分配给进程的数据段的内存量。通常,这些函数是由一个更大的内存管理库函数(如malloc)调用的。brk()将addr的值分配给堆段的结尾,而sbrk()则通过brk()和sbrk()来移动程序断点,它确定了进程堆段的结束。它把你带回到先前的程序中断点。通过调用sbrk(),只需增加0,就可以找到程序中断的当前位置。

语法

#include <unistd.h>
int brk(void *end_data_segment);
void *sbrk(intptr_t increment);

语法的解释

brk()系统调用导致程序在结束数据段位置中断。由于虚拟内存是以页为单位分配的,所以结束数据段被四舍五入到下一个页的边界。试图将程序中断值降低到其初始值以下肯定会导致意想不到的行为,比如当试图访问初始化或未初始化数据段中现在无法访问的部分的数据时,会出现分段故障。有几个因素决定了程序断点可以放置的确切上限。

为什么在C语言中使用brk()系统调用

brk()函数是用来修改分配给调用者进程的内存量的。这种修改是通过改变进程的中断值到addr并提供必要的空间数量来实现的。brk()函数用于修改分配给调用方进程的内存量。随着中断值的上升,分配的空间数量也在上升。新分配的空间有一个0的值分配给它。如果程序先减去然后再增加断点值,重新分配的空间的值就不会被清空。

前提条件

  • 进入Ubuntu 20.04操作系统
  • 安装gcc编译器

用C语言解释brk()的例子

我们设计了一个最简单的例子来阐述在C语言中使用brk()系统调用的概念。让我们在shell中使用nano命令创建一个扩展名为.c的文件。在shell中执行下面的附加命令。

$ nano brk1.c

在Linux操作系统中,GNU nano是一个简单的命令行文本编辑器。它具有所有你认为的文本编辑器的基本功能,以及一些其他的功能。执行后,文件将在GNU编辑器中打开。在你的文件中写下所显示的代码,并根据你的工作要求对其进行一些修改。

在上述截图所附的代码中,Argument count被缩写为argc,参数值被缩写为argv。这些是主函数开始运行时传递给它的变量。在运行时,sysconf函数会检索配置信息。sysconf的参数_SC PAGESIZE是查询页面大小的正确接口。sbrk()通过增加字节数来增加程序的存储空间。通过调用增量为0的sbrk()可以找到目前程序中断的位置。brk()系统调用使程序在结束数据段位置中断。由于虚拟内存是以页为单位分配的,所以结束数据段被四舍五入到下一个页面边界。

通过在Ubuntu 20.04 Linux操作系统终端执行下面引用的指令,可以显示代码的输出。

$ gcc brk1.c
$./a.out

如果你的Ubuntu 20.04操作系统中没有安装GCC,请在shell中运行下面所附的指令来安装它。

$ sudo apt install gcc

输出结果显示在上面的截图中,呈现出页面大小、程序中断地址、字符大小等。

总结

这篇文章是关于C语言编程中的brk()系统调用。我们已经尽力解释了C语言中brk()系统调用的概念和它的用法。其中一个例子已经详细解释过了,以便你理解。通过必要的修改来实现这个例子,你会学到C语言中brk()系统调用的用法。