直入主题:其实在调用malloc(),malloc调用brk(小于128KB)或mmap syscall来获取内存。malloc使用的系统调用。 当 ASLR关闭时,start_brk和brk将指向data / bss段的结尾(end_data). 启用ASLR后,start_brk和brk等于data/ bss段的结尾(end_data)加随机brk偏移量。上图是启用ALSR的虚拟内存分配
上图一中一开始就有堆:我个人的看法是应该是堆表(好比管账的先生对于进出账目记录),而且严格意义上省略了randbrk_offset如有不对,还请大牛斧正
进程启动的时候,其(虚拟)内存空间的初始布局如图1所示。
其中,mmap内存映射文件是在堆和栈的中间(例如libc-2.2.93.so,其它数据文件等),为了简单起见,省略了内存映射文件。
_edata指针(glibc里面定义)指向数据段的最高地址。
程调用A=malloc(30K)以后,内存空间如图2:
malloc函数会调用brk系统调用,将_edata指针往高地址推30K,就完成虚拟内存分配。这里只是完成虚拟地址的分配,在未读写前未分配物理页,图三同理
malloc函数分配内存,如果请求内存大于128K利用mmap系统调用,从堆和栈的中间分配一块虚拟内存。如上图(4)BRK缺点:brk分配的内存需要等到高地址内存释放以后才能释放(例如,在B释放之前,A是不可能释放的,这就是内存碎片产生的原因,什么时候紧缩看下面),而mmap分配的内存可以单独释放。进程调用free(C)以后,C对应的虚拟内存和物理内存一起释放
B,D虚拟内存和物理内存都没有释放,B和D连接起来,变成一块140K的空闲内存
栈,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结果结束也是在栈上进行释放 堆,就是那些由 malloc 等分配的内存块,用 free 来释放 从内存分配的时期来看,堆内存的分配在程序运行时进行,而栈内存的分配会在编译时进行。 从存储的东西来看,堆中一般会存储所需内存比较大的缓冲区,结构体,类对象等等,而栈中一般存储局部变量、返回地址、函数的参数…. 从分配的方式来看,堆内存一般由程序员自己分配,通常使用malloc/calloc/recalloc/分配,free释放,或者 new/delete来管理堆内存, 而栈内存的使用是由编译器自动完成的。
在 32 位系统下,寻址空间 4G,Linux 系统下 0-3G 是用户模式,3-4G 是内核模式
原文请看下面地址
https://sploitfun.wordpress.com/2015/02/11/syscalls-used-by-malloc/
https://www.dazhuanlan.com/2019/10/03/5d94df0488492/
https://www.cnblogs.com/vinozly/p/5489138.html
https://www.anquanke.com/post/id/84930
https://github.com/Apriluestc/2020/blob/master/doc/C%2B%2B/%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86%E7%AF%87.md#c++-%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86
最后一个网址涉及malloc的机制和空闲链表的知识
原文:https://www.cnblogs.com/zuoanfengxi/p/12488197.html