动态内存的底层表示
当我们使用malloc
和free
函数在内存中开辟新内存的时候,我们究竟是改变了什么呢?其实在内存中有一个program break
,这个玩意儿是堆的边界。如果有新的内存被开辟了,这个指针_可能_会移动。
开辟内存的函数
最底层的函数
首先是最底层的两个函数:
|
|
brk()
函数会将program break
的位置设置为参数的位置,从而自动开辟内存。
sbrk()
函数需要指定一个偏移量,program break
的位置会跟随这个偏移量偏移。
C函数
malloc
和free
C的函数就是malloc
和free
了。但是我们还是得了解一下这两个函数的工作原理:
首先malloc
首先按会扫描program break
内空白的部分,如果空白的部分大于分配内存,那么就将空白部分切片并且返回分配内存的内存地址;如果刚好合适就返回内存地址;如果没有合适大小的内存就移动program break
来扩大堆大小。需要注意的是:
- 其不仅会分配内存,还会在内存的前几个字节的地方记录分配内存的大小。
- 扩大堆的大小是按照页的大小来的,而不是按照分配内存大小来的(多分配一点防止下次还要分配)
而free
函数的做法则是这样:
首先free函数有一个空闲列表来以链表的方式存放空闲的内存(放在本身空闲的内存中),当调用free
的时候会在列表中查找以便快速找到要删除的内存。
其他函数
其他函数还有calloc(), realloc()
等
注意alloc()
函数的用法虽然和malloc()
很像,但是却不是在堆上分配的内存,而是通过增加帧栈的方式在堆栈上分配内存。所以使用alloc()
函数分配的内存不能够(也不应该)使用free()
函数消除。由于是在帧栈上分配内存,所以你不应该使用alloc()
函数分配全局变量。
alloc分配内存比较快,而且其分配的内存可以随着帧栈的移除而自动释放。
alloc
函数在alloca.h
头文件中