可能重复:
堆和堆栈内存是如何管理、实现和分配的?
嗨,我的问题是关于堆,而不是数据结构,而是用于动态内存分配的内存区域。
假设我们正在用 C(或者可能是 C++)编写一个程序,并且在其代码深处的某个地方调用了 malloc()(或者在 C++ 的情况下调用了 operator new)。现在分配的内存的位置是什么?编译器(链接器?)是否添加了用作堆的数据段?该段的大小是如何确定的?如果我们尝试分配一块大于整个“堆段”的内存会发生什么?堆会扩大吗?如果是,如何?
可能重复:
堆和堆栈内存是如何管理、实现和分配的?
嗨,我的问题是关于堆,而不是数据结构,而是用于动态内存分配的内存区域。
假设我们正在用 C(或者可能是 C++)编写一个程序,并且在其代码深处的某个地方调用了 malloc()(或者在 C++ 的情况下调用了 operator new)。现在分配的内存的位置是什么?编译器(链接器?)是否添加了用作堆的数据段?该段的大小是如何确定的?如果我们尝试分配一块大于整个“堆段”的内存会发生什么?堆会扩大吗?如果是,如何?
操作系统分配页面,它返回给 malloc/free,然后将这些页面从内存中分解为请求大小的块。操作系统可以分配用户地址空间中尚未请求的任何页面。没有堆段。分配的内存位于操作系统确定的任何位置。
旧的 Unix 实现使用机制-- 系统sbrk()
请求移动最后一个数据段边界。分配内存时,tuntime 库调用系统将数据边界向上移动,并使用新来的内存。
新的操作系统使用虚拟内存,因此 malloc 在必要时向系统请求新的空闲 VM 页面。
独立应用程序(在裸硬件、微控制器等上运行)都分配了内存。库知道所有内存,因为链接描述文件定义了动态区域的符号。例如。类似freemembot
and freememtop
,用于最低和最高可用内存区域位置。
这里有 dlmalloc 内部工作原理的描述(glibc、uClibc 和许多其他地方使用的 malloc() 实现)。
类 Unix 操作系统有两个主要接口用于请求/释放内存:
Windows API 实际上类似于 malloc()/free(),具有 HeapAlloc()/HeapFree() 之类的功能。