c语言 malloc 源码详解,dlmalloc源码剖析之:mALLOc

/*如果你使用linux, douglea malloc已经默认作为glibc的malloc,

新的版本可能用的是ptmalloc(dlmalloc的多线程版本)

如果你用的bsd4.2及以前系统libc用的kingsley的malloc;

BSD(包括freebsd,netbsd,openbsd)4.2以后版本libc用的是PHKmalloc;

如果你用的windows系统用的是microsoft的分配器算法;

不过其他各个系统很容易使用doug lea malloc替换现有的malloc*/

//c语言标准库提供的malloc函数;请注意malloc的几个return出口;

void* mALLOc(size_t bytes)

{

//0~4bytes->nb=16;>4bytes->nb=bytes+2个4字节头,然后对其到8bytes

checked_request2size(bytes, nb);

//如果在fastbin中有可用的块直接从fastbin中分配

if ((unsigned long)(nb) <= (unsigned long)(av->max_fast)) {

fb = &(av->fastbins[(fastbin_index(nb))]);

if ( (victim = *fb) != 0) { //静态变量成员fastbin初始化为0

*fb = victim->fd;

check_remalloced_chunk(victim, nb);

return chunk2mem(victim);

}

}

//如果是<512bytes的小块请求,从smallbin中取一块

if (in_smallbin_range(nb))

{

//根据nb大小定位到smallbin

idx = smallbin_index(nb);

bin = bin_at(av,idx);

//如果该大小的bin列表不为空

if ( (victim = last(bin)) != bin)

{

if (victim == 0) //静态变量成员smallbin初始化是0

malloc_consolidate(av);//第一次进来这里调用init_state函数进行初始化

else {//有空闲块

/* victim

|

\/

bin->first_chunk->chunk->chunk->...->last_chunk

| /\

--------------------------------->|

*/

//按上图将victim从链表中删除,设置victim的下一块的pbit=inuse

//将victim块返回给应用

return chunk2mem(victim);

}

}

}

else {//>512bytes,先释放fastbin中的块

idx = largebin_index(nb);

if (have_fastchunks(av)) //初始化的时候静态变量0,这个条件成立,

malloc_consolidate(av); //合并fastbin中的chunk,放入unsorted_bin

}

//这里是唯一将chunks放入bin的地方

//处理最近被释放或剩余的chunks,如果上次小请求没有完全匹配

//分割出小chunk就会发生

//最外面的for(;;)需要,因为我们无法知道在malloc结束前有合并操作

//因此需要多尝试一次,最多多循环一次

for(;;){

/*

unsorted chunks,所有的从一个chunk中分割出来的剩余chunk首先放到

unsorted chunks链表中,下次malloc调用中有一次被再次使用的机会。

作为一个队列维护。

当free或malloc_consolidate函数中 将剩余chunk放入unsorted chunks链表,

而在malloc函数中被分配或放入其他 正常bin中。

*/

//循环unsorted中每一块,与插入顺序相反,从后面开始匹配查找

while ( (victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) {

bck = victim->bk;//victim:unsorted's last chunk;bck:unsorted's last-two chunk

size = chunksize(victim);

if (in_smallbin_range(nb) //<512bytes

&& bck == unsorted_chunks(av) //unsorted队列中只有一块

&& victim == av->last_remainder //并且这一块是上一次分割剩下的

&& (unsigned long)(size) > (unsigned long)(nb + MINSIZE)) //剩余的chunk必须大于MINSIZE

{

//分割nb出去,剩余的继续放在reminder和unsorted中

return chunk2mem(victim);

}

//unsorted_bin中多于一块chunk,或者剩余一块但不是上一次分割剩余的

//或者剩余的一块大小太小,继续向下

//把最后一块从unsorted freelist中删除

unsorted_chunks(av)->bk = bck;

bck->fd = unsorted_chunks(av);

//如果正好完全匹配,则return

if (size == nb) {

set_inuse_bit_at_offset(victim, size);

check_malloced_chunk(victim, nb);

return chunk2mem(victim);

}

//不是完全匹配就从unsorted_bin移到normal_bin中

if(in_smallbin_range(size)){}

else//注意large-bin中的内存块是有序的,FIFO

{}

}//end while

//对于<512bytes的请求,使用best-fit策略查找当前bin

//注意当前bin是根据应用请求的size直接index定位到的bin

if (!in_smallbin_range(nb)) {//best-fit

if ((victim = last(bin)) != bin //empty or //first最大,但也不能满足请求

&&(unsigned long)(first(bin)->size) >= (unsigned long)(nb)) {

//从后往前找,找到第一个满足请求的

while (((unsigned long)(size = chunksize(victim)) < (unsigned long)(nb)))

victim = victim->bk;

//如果剩余的大小

if (remainder_size < MINSIZE) {

return chunk2mem(victim);

}

else{//分割该块,返回给应用,剩余的块 放入unsorted-bin

return chunk2mem(victim);

}

}

}

//如果unsorted-bin,当前bin都没有满足的,依次查找下一个更大的bin,直到找到一个满足的为止

for (;;) {

//这里使用了bitmap技巧快速查找到匹配的large-bin,具体信息可以参考其他文章

//bit > map说明这个32位中bit后面的bin都是空

/*bit==0??啥意思,index%32==0

index->bit

32 ->1 2^0

1 ->2 2^1

2 ->4 2^2

...

31 -> 2^31

*/

if (bit > map || bit == 0) {//bit怎么会是0??? //从下一个32开始

do {

if (++block >= BINMAPSIZE) /* out of bins */

goto use_top; //所有bin都找完了还没找到,跳到下面use_top

} while ( (map = av->binmap[block]) == 0);

bin = bin_at(av, (block << BINMAPSHIFT));

bit = 1;//从第一位开始

}

//......

//如果找到一块满足的,将该块进行分割

//如果剩余的大小

if (remainder_size < MINSIZE) {

return chunk2mem(victim);

}

else{//分割该块,返回给应用,剩余的块 放入unsorted-bin

return chunk2mem(victim);

}

}//end for(;;),遍历normal-bin

//如果所有bin都没有可用的块

use_top:

//如果top足够大,从top取一块return给用户,修改top指针

if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) {

return chunk2mem(victim);

}

//上面入口处如果请求>512bytes会触发合并fastbin

//在这里:如果fastbins无法满足,smallbins也无法满足,

//而后合并fastbins放入unsorted_bins,

//对于大块再到unsorted_bins找,如果没有精确匹配放入normal_bin

//然后再到normal_bins找best-fit

//如果还没找到,扩展top

//由此可知,如果请求smallsize,则不会触发上述合并fastbins,

//然后会触发到unsorted_bins查找,只有一块上次剩余的小块才会

//被分配,或者精确匹配,否则放入normal_bins

//然后不管larger或small都到normal_bins中查找

//所以在这里对fastbins合并再尝试一次

else if (have_fastchunks(av)) {

assert(in_smallbin_range(nb));

malloc_consolidate(av);

idx = smallbin_index(nb); /* restore original bin index */

}

else //top也没法满足,向OS扩展内存

return sYSMALLOc(nb, av);

}

}//最外层的for(;;)

//end

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/530096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数数C语言,(旧)子数涵数·C语言——让C帮你做计算

之前&#xff0c;我们学过了我们的第一个C程序——hello World。现在开始进一步学习&#xff0c;想一想如何让C帮你做计算。我们先来看代码(我没有新建&#xff0c;还是用之前的hello world.cpp)&#xff1a;好&#xff0c;因为之前在hello World的时候就已经学过了C的基本框架…

求10 翻译c语言,求助:谁能帮我翻译下最基础的C语言,我是新手,谢谢了!

main(){int i,j,p,q,s,n,a[11]{127,3,6,28,54,68,87,105,162,18};/*定义i,j,q,p,s,n和a[11]&#xff0c;并对a数组赋值*/for(i0;i<10;i){pi;qa[i];/* 用p存储i的数值&#xff0c;也就是记住数组的下标。用q记录a[i]的数值&#xff0c;用作比较 */for(ji1;j<10;j)if(qif(p…

c语言之优先级 结合性与自增运算,C语言之优先级、结合性与自增运算

优先级、结合性这些概念在初学的时候并没有放在心上&#xff0c;今天又碰到这个问题&#xff0c;查了不少资料&#xff0c;再次做个总结。在标准C语言的文档里&#xff0c;对操作符的结合性并没有做出非常清楚的解释。一个满分的回答是&#xff1a;它是仲裁者&#xff0c;在几个…

android设置输入框输入字符限制,Android EditText限制输入字符的方法总结

Android EditText限制输入字符的方法总结最近项目要求限制密码输入的字符类型&#xff0c; 例如不能输入中文。 现在总结一下EditText的各种实现方式&#xff0c; 以比较各种方法的优劣。第一种方式&#xff1a; 设置EditText的inputType属性&#xff0c;可以通过xml或者Ja…

android动态改变菜单栏,Android动态设置主题(使用RxBus模式)

之前写过一篇文章&#xff1a;RxBus的实现及简单使用。今天我们尝试使用RxBus动态切换主题。一、定义主题颜色color.xml#F44336#D32F2F#F44336#E91E63#C2185B#E91E63#795548#5D4037#795548#2196F3#1976D2#2196F3#607D8B#455A64#607D8B#FFEB3B#FBC02D#FFEB3B#673AB7#512DA8#673A…

android 图片分析,Android图片处理实例分析

本文实例讲述了Android图片处理的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;package cn.szbw.util;import Android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.…

android开发按钮颜色,Android编程实现简单设置按钮颜色的方法

本文实例讲述了Android编程实现简单设置按钮颜色的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;1.工程目录a.在res目录-新建drawble文件夹放入自定义图片2.main.xmlandroid:orientation"vertical"android:layout_width"fill_parent"androi…

艾默生变频器ev1000故障代码_国产变频器型号大全,梳理国产变频的前世今生!...

在工控领域&#xff0c;变频器已经广为所知且应用范围广泛&#xff0c;各方对变频器能给出形形色色的描述。维基百科给出的定义&#xff1a;“变频器(variable frequency drive&#xff0c;常见缩写VFD)&#xff0c;也称为变频驱动器或驱动控制器。变频器是可调速驱动系统的一种…

android音乐播放器案例,Android MediaPlayer实现音乐播放器实例代码

Android MediaPlayer实现音乐播放器1、布局文件android:layout_width"fill_parent"android:layout_height"fill_parent"android:orientation"vertical" >android:id"id/hint"android:layout_width"wrap_content"android:…

单边指数信号的特点_今日股市分析:上证指数若能守住3400,蓄力反弹就有戏...

昨日整体概况上涨&#xff1a;848只 下跌&#xff1a;3009只涨停&#xff1a;69只 跌停&#xff1a;12只昨天的上证指数低开低走&#xff0c;午后冲红又回落&#xff0c;另一边的创业板却是单边下行跌超3%&#xff0c;板块方向农业、洪水概念股、还有电力板块较强。按照昨日置顶…

万丰科技机器人排名_机器人系统集成“7宗最”

摘要&#xff1a;对于众多集成商而言&#xff0c;作为典型的“夹心饼奥利奥”&#xff0c;面对客户的各种要求&#xff0c;“不敢勉强你&#xff0c;只好为难自己”系真实写照。1、企业数量最多GGII统计数据显示&#xff0c;截至2019年年底&#xff0c;中国工业机器人产业企业数…

android 电池高温关机,Android 关机问题分析指南

本篇文章主要介绍 Android 开发中的 关机 部分知识点&#xff0c;通过阅读本篇文章&#xff0c;您将收获以下内容:1 . 确认是亮屏关机还是灭屏关机&#xff1f;关机时是否有播放关机动画&#xff1f;2 . 是直接关机还是关机后会自动重启&#xff1f;3.异常关机时&#xff0c;连…

android switch 未定义,在switch语句中初始化时未定义的变量?

问题本身就是一个明显的答案.无论如何,这是我的代码片段......switch(cSet)...case 8:{ //Special CharactersfinalSet special;char* charSet new char[special.size() 1];charSet[special.size()] 0; //Append null terminatormemcpy(charSet, special.c_str(), special.…

android 克隆对象,克隆会破坏单例对象吗?

假设有这样一个场景&#xff0c;如果复制的目标对象恰好是单例对象&#xff0c;那会不会破坏单例对象呢&#xff1f;当然&#xff0c;我们在已知的情况下肯定不会这么干&#xff0c;但如果发生了意外怎么办&#xff1f;不防来修改一下代码。public class ConcretePrototype imp…

转网口显示未识别的网络_已有1700万用户携号转网 超99%用户1小时内办结

携号转网是利国利民的大举措&#xff0c;受到了很多电信用户的拥护和支持。12月15日&#xff0c;工信部副部长刘烈宏在某会议上进行报告指出&#xff0c;目前我国 “携号转网”服务已经累计有 1700 万用户完成携转&#xff0c;一小时携转成功办结率超过 99%。已有1700万用户携号…

adb 更新 android sdk,[转载]安装Android时SDK AVD MANAGER时更新报错的解决办法

最近安装Android SDK时&#xff0c;发现更新时出现“A folder failed to be renamed ormoved.”等类似错误。经过测试和G后发现解决办法目前有两种情况&#xff1a;1、确实是因为打开了相关目录或者其他程序占用率文件夹句柄。关闭相关资源管理器或者关闭相关程序即可&#xff…

2020.2idea怎么创建html项目_陈肆横项目日记:百度百科怎么创建自己的名字

百度百科是一个介绍人物很好的平台&#xff0c;很多的都想创造属于自己的百度百科。而人物百科词条&#xff0c;是百度百科专门为知名人物提供个人信息展示的平台。创建一个属于自己的百度百科词条&#xff0c;就相当于拥有了一张名片&#xff0c;不仅有着影响力与知名度的传播…

android c++ gizp 调用 so,使用ndk-build编译 android调用的so库

前沿编译so的方法有两种方法第一种就是编写原生的makefile文件利用gcc进行编译&#xff0c;这里我讲解的是另外一种。采用NDK提供的ndk-build编译。简介使用ndk编译的时候需要介绍它的脚本文件,Android.mk和Application.mk&#xff0c;但是Application.mk是可选的&#xff0c;用…

elctron项目_electron项目结构介绍

#项目结构my-project├─ .electron-vue(webpack配置文件)│ └─ build.js(生产环境构建代码)│ └─ dev-client.js(热加载相关)│ └─ dev-runner.js(开发环境启动入口)│ └─ webpack.main.config.js(主进程配置文件)│ └─ webpack.renderer.config.js(渲染进程配…

无法启动mysqll1006_CentOS7下MySQL服务启动失败原因及解决方法

在重启阿里的CentOS7服务器后,重启MySQL 出现错误Starting mysqld (via systemctl):Job for mysqld.service failed because the control process exited with error code.See "systemctl status mysqld.service" and "journalctl -xe" fordetails.[FAILED…