sbrk()和brk() 系统的底层会维护一个位置,通过位置的移动完成内存的分配和回收。映射内存时 以一个内存页作为基本单位。
void* sbrk(int increment)
参数是增量
增量为正数时,分配内存
增量为负数时,回收内存
增量为0时,取当前的位置
返回 移动之前的位置(可用内存的首地址),这个返回值对于增量为负数的情况没有意义。
sbrk() 在分配内存时很方便,但在回收内存时比较麻烦;brk()则相反。 ->
开发中,一般用sbrk()分配内存,用brk()回收内存。
brk()的使用方式就是直接传递一个地址过来,做新的位置。
brk()必须和sbrk()结合使用,获得第一个位置。
sbrk()参数为位置,表示从当前位置开始移动多少位.sbrk(0)获取当前位置.
brk()参数也为移动的位置,但是这个位置为从第一个位置开始.
下面是一些帮助理解的小例子:
//brk.c #include <stdio.h> #include <unistd.h> int main() { int* p = sbrk(0); brk(p+1);//分配空间 brk(p+100);//分配空间 brk(p+50);//释放空间 brk(p);//全部释放 int* pa = sbrk(4);//分配4bytes int* pb = sbrk(0); brk(p+100);//分配396bytes void* p2 = sbrk(4); //404 printf("p=%p\n", p); printf("p2=%p\n", p2); printf("end=%p\n", sbrk(0)); //------------------------------- int* start = sbrk(100); int* p10 = sbrk(4); int* p20 = sbrk(4); //... brk(start); }
这里的内存分配感觉有些麻烦,不过释放很轻松.
//sbrk.c #include <stdio.h> #include <unistd.h> int main() { int* p1 = sbrk(4);//分配4个字节的内存空间 printf("p1=%p\n", p1); //*(p1+1023) = 1000; int* p2 = sbrk(4); int* p3 = sbrk(4); int* p4 = sbrk(4); printf("p2=%p\n", p2); printf("p3=%p\n", p3); printf("p4=%p\n", p4); sbrk(-12);//释放12个字节的内存空间 int* cur = sbrk(0);//获取sbrk后台的当前位置 printf("cur=%p\n", cur); sleep(15); //sbrk(-4);//再次释放4个字节的内存空间 sbrk(4092+1); while(1); }
sbrk分配比较轻松,释放麻烦.
所以我们可以两个结合了使用
#include <stdio.h> #include <unistd.h> int main() { void* p = sbrk(0); //得到第一个地址 int* p1 = p; printf("p1=%p\n", p1); int* p2 = sbrk(4); int* p3 = sbrk(4); int* p4 = sbrk(4); printf("p2=%p\n", p2); printf("p3=%p\n", p3); printf("p4=%p\n", p4); brk(p1+1024);//分配整个页面的空间 brk(p1+512);//释放一半空间 brk(p1);//释放所有空间 }