7.1 在堆上分配内存
所谓堆是一段长度可变的连续虚拟内存,始于进程未初始化数据段的末尾,随着内存的分配和释放而增减。
通常将堆的当前内存边界称为"program break".
brk 和sbrk
这两个函数的作用就是通过设置program break 的位置改变堆的大小。
函数原型:
但是在实际代码中很少使用这些系统调用,但是了解他们有助于弄清内存分配的工作过程。
brk()会将program break设置为参数end_data_segment所指定的位置
sbrk()会将program break在原有地址上增加从参数increment传入的大小
malloc()和free()
free()并不降低program break的位置,而是将这块内存添加到空闲内存列表中。
free(NULL)将什么都不做。
free()函数会在释放内存时将相邻的空闲内存块合并为一整块更大的内存。
malloc的实现:
首先扫描之前由free所释放的空闲内存块列表,以求找到尺寸大于或等于要求的一块内存空间。
如果找不到合适的空闲内存块,malloc会调用sbrk()分配更多的内存(以虚拟内存页大小的数倍)。
free的实现:
将内存块置于空闲内存列表中。
calloc()和realloc()
calloc(): 用于分配size个numitems大小的数据
realloc(): 用于调整一块内存的大小
分配对齐的内存:
分配size个字节,起始地址是boundary的整数倍,而boundary必须是2的整数次幂。
posix_memalign感觉没啥用就没看。。
7.2 在堆栈上分配内存:alloca()
- alloca通过增加栈帧的大小从堆栈上分配内存。
- 同时,alloca可能造成内存溢出。
- 注意:不能在一个函数的参数列表中调用alloca().
使用alloca()来分配内存相对于malloc的优势:
- alloca()的速度快于malloc()
- alloca()分配的内存会随帧栈的移除而自动释放,及超过生命周期时。