stackoverflow上的回答: 

In many malloc/free implementations, free does normally not return the memory to the operating system (or at least only in rare cases). The reason is, that you will get gaps in your heap and thus it can happen, that you just finish off your 2 or 4 GB of virtual memory with gaps. This should be avoided of course, since as soon as the virtual memory is finished, you will be in really big trouble. The other reason of course is, that the OS can only handle memory chunks that are of a specific size and alignment. To be specific: Normally the OS can only handle blocks that the virtual memory manager can handle (most often multiples of 512 Bytes eg. 4KB).

So returning 40 Bytes to the OS will just not work. So what does free do?

Free will put the memory block in its own free block list. Normally it also tries to meld together adjacent blocks in the address space. The free block list is just a circular list of memory chunks which have of course some administrative data in the beginning. This is also the reason, why managing very small memory elements with the standard malloc/free is not efficient. Every memory chunk needs additional data and with smaller sizes more fragmentation happens.

The free-list is also the first place that malloc looks at when a new chunk of memory is needed. It is scanned before it calls for new memory from the OS. When a chunk is found that is bigger then the needed memory, it is just divided into two parts. One is returned to caller, the other is put back into the free list.

There are many different optimizations to this standard behaviour (for example for small chunks of memory). But since malloc and free must be so universal, the standard behaviour is always the fallback when alternatives are not usable. There are also optimizations in handling the free-list -- for example storing the chunks in lists sorted by sizes. But all optimizations also have their own limitations.

首先malloc()/free()的操作取决于操作系统和编译器的实现。一般来说当你调用malloc(),系统会从堆中给你分配一块足够大的空闲内存,并返回指向它的指针,并且标记它不再空闲。当调用free(),系统检查这块内存的大小,并把它加入到free列表中,而不是立即回收它的内存,因为操作系统只能处理特定大小且连续的内存块:一般来说是512Bytes的倍数。Free内存块链表的另一个作用是,当调用malloc()时,系统会首先从这个表中查找符合要求的内存块,如果找不到适合大小的内存块再向操作系统申请新的内存空间。

malloc 申请得到的内存后,再 free 释放它的时候,操作系统会立即收回那块内存吗?的更多相关文章

  1. 《C语言中分配了动态内存后一定要释放吗?》

    问:比如main函数里有一句 malloc(),后面没有free()1.那么当main结束后,动态分配的内存不会随之释放吗?2.如果程序结束能自动释放,那么还加上free(),是出于什么考虑? 答: ...

  2. C++ - free()函数释放内存后的指针行为

    一个指针释放后不置空的后果: free(p)之后原本那块内存的数据已经被释放了,内存重新收回.但此时的指针变量依然指向那块内存,在以后的代码中若不小心继续调用指针变量,会出现不可预料的错误. 不置空的 ...

  3. 有关于malloc申请内存和free内存释放

    malloc工作机制: malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表(堆内存).调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块. ...

  4. 【VS开发】malloc申请内存错误分析

    每个进程会有4G的虚拟地址空间, malloc得到的的地址都是虚拟地址, 并且当malloc的时候, 操作系统并不会将实际的内存分配给进程的, 所以malloc只会占用进程自身的虚拟地址空间.我以前也 ...

  5. 关于malloc申请的动态内存的问题

    http://bbs.bccn.net/thread-331344-1-1.html #include<stdio.h>#include<stdlib.h>int main(v ...

  6. PE文件从文件加载到内存,再从内存读取,然后存盘到文件

    // mem.cpp : 定义控制台应用程序的入口点. //PE文件从文件加载到内存,再从内存读取,然后存盘到文件 #include "stdafx.h" #include < ...

  7. ndk学习之C语言基础复习----虚拟内存布局与malloc申请

    在这一次中来学习一下C语言的内存布局,了解它之后就可以解释为啥在用malloc()申请的内存之后需要用memset()来对内存进行一下初始化了,首先来了解一下物理内存与虚拟内存: 物理内存:通过物理内 ...

  8. Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8 (转)

    Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8http://www.crifan.com/android_emulator_ ...

  9. 【已解决】Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8

    [问题] 折腾: [已解决]Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8 过程中,增大对应AVD的内存为2G后,结果无法启 ...

随机推荐

  1. 网易云课堂_程序设计入门-C语言_第六章:数组_1多项式加法

    1 多项式加法(5分) 题目内容: 一个多项式可以表达为x的各次幂与系数乘积的和,比如: 现在,你的程序要读入两个多项式,然后输出这两个多项式的和,也就是把对应的幂上的系数相加然后输出. 程序要处理的 ...

  2. Wormholes(SPFA+Bellman)

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36860   Accepted: 13505 Descr ...

  3. Javaweb整合mongo和kettle6.0的环境配置

    为了编译能通过,maven需要加入仓库地址以及一些必须要的包的依赖情况: pentaho中央仓库: 在properties里面配置版本号: <kettle.version>6.0.0.0- ...

  4. 使用VC++通过远程进程注入来实现HOOK指定进程的某个API

    前阵子读到一篇关于<HOOK API入门之Hook自己程序的MessageBoxW>的博客,博客地址:http://blog.csdn.net/friendan/article/detai ...

  5. [STL源码剖析]RB-tree的插入操作

    RB-tree的性质 对于RB-tree,首先做一个了解,先看一张维基百科的RB-tree: 再看RB-tree的性质: 性质1. 节点是红色或黑色. 性质2. 根是黑色,所有叶子都是黑色(叶子节点指 ...

  6. Swift 基本基本运算符

    Swift 1,赋值运算符 Swift赋值表达式是没有值的,不支持连续赋值. 2,算术运算符 除数可为0 var f=1/0.0 求余的结果的正负取决于被除数 3,溢出运算符* 根据二进制来进行计算 ...

  7. C#开发者通用性代码审查清单

    这是为C#开发者准备的通用性代码审查清单,可以当做开发过程中的参考.这是为了确保在编码过程中,大部分通用编码指导原则都能注意到.对于新手和缺乏经验(0到3年工作经验)的开发者,参考这份清单编码会很帮助 ...

  8. jjs 产生undefined的情况

    <script type="text/javascript"> var outObj = { type :"java" } function inn ...

  9. B/S结构和C/S结构

    概念: C/S结构,即Client/Server(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,可以充分利用两端硬件环境 ...

  10. python3 模拟登录网站

    最近学习python,因经常登录公积金网站查看公积金缴存还款情况,so网上找了写脚本,修改了一下,方便获取网页中的数据. 使用谷歌浏览器F12查看登录请求内容 1.request header需要参数 ...