系統大全為您提供ChunkC標準庫在管理分配出去的heap時的基本單位是chunk,chunk只是一個邏輯概念,它的數據結構如下:structmalloc_chunk{size_tprev_size;size_tsize;structmalloc_chunk*fd;structmalloc_chunk*bk;structmalloc_chunk*fd_nextsize;structmalloc_chunk*bk_nextsize;};如果一個chunk是free的狀態,那么它的fd和bk就構成一個雙鏈表,記錄著那些已經被用戶free了內存,這樣以后就可以從這里直接分配或者合并成為大的空閑塊以后再分配。如果一個chunk已經被alloc了,那么此時從size之后就是用戶的數據,也就是說fd、bk等沒有意義,這個從注釋中不難看出。當一個chunk被分配出去時,size記錄了這個chunk中實際分配給用戶程序的內存大小,也就是我們調用malloc時的那個參數值,而prev_size記錄的是與當前chunk相鄰的上一個chunk的大小。這樣設計的原因是可以快速地定位/合并相鄰的chunk.例如,如果當前chunk地址為char*p,那么上/下一個chunk的地址分別就是p-p->prev_size和p+p->size.簡單分析下下面這兩個宏就一目了然了:(1)從chunk得到用戶指針(這里SIZE_SZ即sizeof(size_t))#definechunk2mem(p)((void_t*)((char*)(p)+2*SIZE_SZ))(2)從用戶指針得到chunk地址#definemem2chunk(mem)((mchunkptr)((char*)(mem)-2*SIZE_SZ))在分配內存時,chunk的對其單位是8Byte,這樣size的低3位就都是0,那么就可以作為其他用途。在glibc中有兩個定義:#definePREV_INUSE0x1#defineIS_MMAPPED0x2這里PREV_INUSE記錄了上一個chunk是否被使用(如果被分配則為1),而IS_MMAPPED標識當前chunk是否是通過mmap分配得到。下面這些宏可以加深我們對chunk的理解://獲取當前chunk(p)的下一個chunk#definenext_chunk(p)((mchunkptr)(((char*)(p))+((p)->size&~PREV_INUSE)))//獲取當前chunk(p)的上一個chunk#defineprev_chunk(p)((mchunkptr)(((char*)(p))-((p)->prev_size)))//判斷當前chunk(p)是否被使用,注意:p的inuse位信息保存在下一個相鄰chunk的size中#defineinuse(p)((((mchunkptr)(((char*)(p))+((p)->size&~PREV_INUSE)))->size)&PREV_INUSE)//將當前chunk(p)設置為被使用,也即設置下一個相鄰chunk中size的最低位為1#defineset_inuse(p)((mchunkptr)(((char*)(p))+((p)->size&~PREV_INUSE)))->size|=PREV_INUSEmalloc數據結構這個數據結構記錄了系統當前分配內存的狀態,默認情況下,當分配內存小于64B時通過fastbin分配,它是一個cachingallocator,也就是說一種memorypool.當分配內存大于512B時,系統按照best-fit算法分配,也就是可以滿足需求的最小size的chunk.介于二者之間的情況比較復雜。structmalloc_state{mutex_tmutex;intflags;mchunkptrfastbins[NFASTBINS];mchunkptrtop;mchunkptrlast_remainder;mchunkptrbins[NBINS*2-2];unsignedintbinmap[BINMAPSIZE];structmalloc_state*next;INTERNAL_SIZE_Tsystem_mem;INTERNAL_SIZE_Tmax_system_mem;};malloc實現(void*malloc(size_tsize))該調用在內部實現為_int_malloc(mstateav,size_tbytes)。主要步驟如下:1、確定內部分配內存大小,它是用宏request2size計算得到。:#definerequest2size(req)(((req)+SIZE_SZ+MALLOC_ALIGN_MASK
fastbins[idx]);if((victim=*fb)!=0){if(__builtin_expect(fastbin_index(chunksize(victim))!=idx,0))malloc_printerr(check_action,"malloc():memorycorruption(fast)",chunk2mem(victim));*fb=victim->fd;check_remalloced_chunk(av,victim,nb);void*p=chunk2mem(victim);if(__builtin_expect(perturb_byte,0))alloc_perturb(p,bytes);returnp;}}fastbin_index(nb):?這是一個宏,定義為#definefastbin_index(sz)((((unsignedint)(sz))》3)-2)。觀察malloc_state數據結構,它有一個fastbin的指針數組,每個數組成員分配是一個單鏈表的表頭,可見fastbin[i]專門用于分配大小為16+8i的內存塊。*fb=victim->fd:當執行到這一行時,fastbin[idx]肯定不為空,也就是說當前內存分配可以直接從fastbin中滿足,那么下面自然是從單鏈表中取下victim這個chunk,而這行賦值語句正是完成這個任務。這里相當于fastbin[idx]這個指針指向了victim這個chunk的后繼(victim->fd),也就是說將victim從鏈表中移除。void*p=chunk2mem(victim)前文中已經分析過這個宏了,它返回的是chunk內用戶內存的首地址。3、如果分配內存大于64B,但是小于512B,那么仍屬于小塊內存請求,從smallbin中分配if(in_smallbin_range(nb)){idx=smallbin_index(nb);bin=bin_at(av,idx);if((victim=last(bin))!=bin){if(victim==0)malloc_consolidate(av);else{bck=victim->bk;set_inuse_bit_at_offset(victim,nb);bin->bk=bck;bck->fd=bin;if(av!=&main_arena)victim->size|=NON_MAIN_ARENA;check_malloced_chunk(av,victim,nb);void*p=chunk2mem(victim);if(__builtin_expect(perturb_byte,0))alloc_perturb(p,bytes);returnp;}}}smallbin_index(nb):它也是一個宏,它定義等價于#definesmallbin_index(sz)(((unsigned)(sz))》3))。這里因為系統將512B大小以下的閑置內存塊都組織為雙鏈表???以上就是系統大全給大家介紹的如何使的方法都有一定的了解了吧,好了,如果大家還想了解更多的資訊,那就趕緊點擊系統大全官網吧。??本文來自系統大全http:///如需轉載請注明!推薦:win7純凈版