自从我被介绍到C
,有人告诉我,在C
动态内存分配是使用中的函数完成的malloc
家庭。我还了解到,使用动态分配内存malloc
分配在进程的堆部分。
各种操作系统教科书都这么说malloc
涉及系统调用(虽然并不总是但有时)来将堆上的结构分配给进程。现在假设malloc
返回指向堆上分配的字节块的指针,为什么它需要系统调用。函数的激活记录放置在进程的堆栈部分中,并且由于“堆栈部分”已经是进程虚拟地址空间的一部分,所以激活记录的压入和弹出、堆栈指针的操作,只需从虚拟地址空间的最高可能地址。它甚至不需要系统调用。
现在基于同样的理由,由于“堆部分”也是进程虚拟地址空间的一部分,为什么需要系统调用来在该部分中分配字节块。例行公事就像malloc
可以自行处理“空闲”列表和“已分配”列表。它需要知道的只是“数据部分”的结尾。某些文本说系统调用对于“将内存附加到进程以进行动态内存分配”是必要的,但是如果malloc
在“堆部分”分配内存为什么在过程中需要将内存附加到进程malloc
?可以简单地取自过程中已经一部分的部分。
在阅读 Kernighan 和 Ritchie 所著的《C 编程语言》[2e] 时,我发现了他们对malloc
函数[第 8.7 节第 185-189 页]。作者说:
malloc
根据需要调用操作系统获取更多内存。
这就是操作系统文本所说的,但与我上面的想法相反(如果malloc
在堆上分配空间)。
由于向系统请求内存是一个相对昂贵的操作,因此作者不会在每次调用时都这样做malloc
,所以他们创建了一个函数morecore
其要求至少NALLOC
单位;这个较大的块根据需要被切碎。基本的空闲列表管理是通过free
.
但问题是作者使用sbrk()
向操作系统请求内存morecore
。现在维基百科说:
brk
and sbrk
是 Unix 和类 Unix 操作系统中使用的基本内存管理系统调用,用于控制分配给数据段的过程。
Where
数据段(通常表示为 .data)是目标文件或程序的相应地址空间的一部分,其中包含初始化的静态变量,即全局变量和静态局部变量。
我猜这不是“堆部分”。 [数据部分是上图中从下数第二部分,而堆是从下数第三部分。]
我完全困惑了。我想知道到底发生了什么以及这两个概念如何正确?请通过将分散的碎片连接在一起来帮助我理解这个概念......