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.pswp.cn/news/530096.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530096.shtml
英文地址,請注明出處:http://en.pswp.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…