精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Glibc堆內存管理:原理、機制與實戰

系統 Linux
GlibC Malloc 作為 Linux 環境下被廣泛使用的內存分配器,其運作機制極其復雜且微妙。GlibC Malloc for Exploiters 項目就像一把精準的手術刀,深入到 GlibC 的內部,清晰地揭示了 malloc 與 free 函數是如何管理堆內存的,尤其是在那些易受攻擊的場景下,它們的行為模式更是被剖析得淋漓盡致。

在內存管理領域,glibc(GNU C Library)通過 brk 和 mmap 兩大系統調用,構建了一套高效的堆內存管理機制。這種設計大幅減少了系統調用的頻次,顯著提升內存利用率。在 glibc 的管理架構中,堆內存以層級化的方式組織,包含分配區(Arena)、堆(Heap)和內存塊(Chunk)。其中,主 Arena 依賴 brk 系統調用實現內存分配,而子 Arena 則通過 mmap 完成內存獲取。在多線程程序運行時,每個線程通常會擁有專屬的 Arena,主線程與子線程的堆空間各自獨立管理,互不干擾。

內存塊在運行過程中存在空閑與已使用兩種狀態,glibc 通過 fast bins、small bins、large bins 和 unsorted bin 四類數據結構,對內存塊進行有序組織,從而加速內存的分配與釋放操作。在具體實現 malloc 和 free 函數時,glibc 遵循 “先小后大,最佳適配” 原則,同時還會根據實際需求動態擴展堆空間,并采用合理的內存釋放策略,確保內存資源的高效利用。

一、Glibc 堆內存管理:為何重要?

在編程的世界里,內存就像是程序運行的舞臺,每一個變量、每一段數據都在這個舞臺上登場、表演和落幕。而 Glibc 堆內存管理,無疑是這場演出中至關重要的幕后導演,它默默掌控著內存的分配與釋放,確保程序能夠順利運行。

在實際開發中,內存相關的問題屢見不鮮,它們就像隱藏在暗處的 “定時炸彈”,隨時可能給程序帶來嚴重的影響。程序崩潰便是其中一個常見的問題。想象一下,你精心編寫的程序在運行一段時間后突然崩潰,所有的努力瞬間化為泡影,這是多么令人沮喪的事情。而內存泄漏往往是導致程序崩潰的罪魁禍首之一。當程序中分配的內存沒有被正確釋放時,隨著時間的推移,可用內存會越來越少,最終導致系統內存耗盡,程序不得不終止運行。這種情況在長時間運行的服務器程序中尤為常見,一個小小的內存泄漏可能會在不知不覺中引發服務器的崩潰,給用戶帶來極大的不便。

除了程序崩潰,性能下降也是內存問題的一個重要表現。當內存管理不善時,程序可能會頻繁地進行內存分配和釋放操作,這會導致內存碎片化。內存碎片化就像是一個雜亂無章的倉庫,雖然倉庫的總容量足夠,但由于物品擺放混亂,需要使用某個物品時卻很難快速找到,從而降低了程序的運行效率。在一些對性能要求極高的應用場景中,如游戲開發、大數據處理等,內存碎片化可能會導致游戲卡頓、數據處理速度變慢,嚴重影響用戶體驗。

Glibc 堆內存管理在編程中占據著關鍵地位,它直接關系到程序的穩定性和性能。如果把程序比作一輛汽車,那么內存就是汽車的燃油,而 Glibc 堆內存管理則是汽車的燃油噴射系統,它能夠精準地控制燃油的供應,確保汽車能夠高效、穩定地行駛。只有深入理解并合理運用 Glibc 堆內存管理,才能編寫出高質量、高性能的程序,避免內存問題帶來的種種困擾。

二、Glibc 堆內存管理基礎

2.1進程內存布局

在計算機系統中,進程的內存布局就像是一個精心規劃的城市,不同的區域承擔著不同的功能。對于 32 位系統而言,其進程內存布局有著獨特的結構。整個內存空間就像一座擁有不同功能分區的大廈,棧區位于大廈的較高樓層,它由編譯器自動分配釋放,主要存放函數的參數值、局部變量的值等。棧區就像是一個臨時的物資存放點,隨著函數的調用和結束,物資(數據)不斷地進出。它從高地址向低地址生長,就像樓層從高往低依次被占用。

圖片圖片

堆區則位于大廈的較低樓層,它是動態內存分配區域,通過malloc、new、free和delete等函數來管理,一般由程序員分配釋放,若程序員不釋放,程序結束時可能由系統回收 。堆區就像是一個可以自由擴建的倉庫,其大小受限于計算機系統中有效的虛擬內存,向高地址擴展,由于系統是用鏈表來存儲空閑內存地址的,所以它是不連續的內存區域。

數據區存放著在源代碼中有預定義值的全局變量和靜態變量,它就像是大廈中存放重要物資儲備的區域,這些物資(數據)在程序運行過程中有著重要的作用。

未初始化變量區(BSS)存儲未被初始化的全局變量和靜態變量,它就像是一個等待填充物資的倉庫,在程序運行前,這些變量雖然已經分配了空間,但還沒有具體的值。

代碼區則存儲只讀的程序執行代碼,即機器指令,它就像是大廈的控制中心,指揮著整個程序的運行。

而在 64 位系統中,雖然內存布局的基本概念與 32 位系統相似,但由于其擁有更大的虛擬地址空間,就像是一座更加龐大的大廈,在內存布局上也有一些不同之處。64 位系統采用與 32 位經典內存布局相似的方式,棧區和堆區的生長方向、作用等與 32 位系統類似,但在地址范圍和內存管理的一些細節上有所差異。例如,64 位系統可以支持更大的堆空間和棧空間,這使得程序在處理大規模數據和復雜函數調用時更加從容。

2.2關鍵系統調用:brk 與 mmap

在 Glibc 堆內存管理的底層,brk和mmap這兩個系統調用扮演著舉足輕重的角色,它們就像是內存管理這座大廈的基石,為整個內存管理機制提供了底層支持。

brk系統調用主要用于改變進程的數據段大小,它就像是一個可以調整倉庫大小的工具。數據段是進程地址空間中存儲動態分配數據的區域,如全局變量、靜態變量、堆等。當進程需要分配更多內存時,brk系統調用能夠擴展進程的堆,通過將當前堆的末尾地址移動到所需內存塊的末尾地址,從而為進程提供新的內存空間。相反,當進程需要釋放已經分配的內存時,可以通過調用brk系統調用,將堆的末尾地址移動回去,釋放不再需要的內存。

brk分配的內存是連續的,適合小塊內存的頻繁分配和釋放,就像一個小倉庫,對于一些小型物資(小塊內存)的存放和取出非常方便。例如,當一個程序需要頻繁地分配和釋放一些小型的數據結構時,brk系統調用可以高效地完成這些操作。

lang=c
#include <unistd.h>
int brk(void *addr);
void *sbrk(intptr_t increment);

mmap系統調用則像是一個功能強大的大型倉庫構建器,它用于在進程的虛擬地址空間中創建一個內存映射。它可以將文件或者設備映射到進程的地址空間,使得進程可以像訪問內存一樣訪問文件或設備。mmap的功能非常豐富,它可以創建匿名映射,即不與任何文件關聯的內存映射,用于在進程間共享內存,或者作為大塊內存的分配器。

它還可以用于文件映射,將一個文件的全部或部分內容映射到進程的虛擬內存中,進程可以像訪問內存一樣讀寫文件的內容,而不需要顯式地進行文件 I/O 操作,對內存的修改會自動同步到文件中,減少了數據拷貝和系統調用的次數。在處理大型文件時,如數據庫文件、日志文件等,mmap可以大大提高文件的讀寫效率。此外,mmap還常用于實現進程間通信的機制,如共享內存、消息隊列等,多個進程可以映射同一個文件或匿名映射到它們的地址空間,實現共享內存,從而高效地進行數據交換和同步。

lang=c
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);

在 Glibc 堆內存管理中,malloc函數在分配內存時,會根據請求的內存大小來選擇使用brk還是mmap。當請求的內存大小小于一定閾值(在大多數系統中,這個閾值通常為 128KB )時,malloc函數會優先使用brk系統調用來分配內存,因為brk的系統調用開銷較小,適合頻繁的小塊內存分配;當請求的內存大小大于這個閾值時,則會使用mmap系統調用,因為mmap可以分配大塊連續的虛擬內存,且可以獨立管理每個內存塊,能夠滿足大塊內存的分配需求。

三、Glibc 堆內存管理核心機制

圖片圖片

3.1分配區(Arena)探秘

在 Glibc 堆內存管理的復雜體系中,分配區(Arena)就像是一個大型的內存資源調配中心,它在內存管理中扮演著至關重要的角色,是理解整個內存管理機制的關鍵所在。

Arena 本質上是一個內存區域,它通過sbrk或mmap系統調用為線程分配堆區。在一個進程中,Arena 分為主分配區(main arena)和非主分配區(sub - arena) 。主線程擁有自己獨立的主分配區,即main_arena,它就像是內存調配中心的總部,在程序啟動時就被創建,并且通過sbrk系統調用從操作系統獲取內存,這些內存主要來自于進程的堆區。main_arena在整個內存管理中具有特殊地位,它管理著所有線程共享的堆內存,就像一個大型倉庫,存放著各種內存資源,等待著被分配給各個線程使用。

而對于多線程環境下的子線程,它們所對應的非主分配區則是通過mmap系統調用創建的。當線程數量較多時,并非每個線程都能擁有自己獨立的 Arena,因為 Arena 的數量是有限的,這與 CPU 核數相關。在 32 位系統中,Arena 數量上限 = 2核數;在 64 位系統中,Arena 數量上限 = 8核數。當線程數量超過這個上限時,就會出現線程之間共享 Arena 的情況。這就好比多個工人在有限的倉庫中領取物資,當倉庫數量不足時,就需要多個工人共享一個倉庫。

當線程調用malloc申請內存時,線程會先查看線程私有變量中是否已經存在一個分配區。如果存在,則對該分配區加鎖,加鎖成功的話就用該分配區進行內存分配;失敗的話則搜索環形鏈表找一個未加鎖的分配區。如果所有分配區都已經加鎖,那么malloc會開辟一個新的分配區加入環形鏈表并加鎖,用它來分配內存。這種機制就像是工人在領取物資時,會先查看自己專屬的倉庫是否可用,如果不可用,就會去尋找其他空閑的倉庫,若所有倉庫都被占用,就會新建一個倉庫來存放物資。

Arena的數據結構:

struct malloc_state
{
  /* Serialize access.  */
  mutex_t mutex;//互斥量,用于多線程共享一個Arena

  /* Flags (formerly in max_fast).  */
  int flags;

#if THREAD_STATS
  /* Statistics for locking.  Only used if THREAD_STATS is defined.  */
  long stat_lock_direct, stat_lock_loop, stat_lock_wait;
#endif


/* 回收箱:fastbins,bins */
  /* Fastbins */
  mfastbinptr fastbinsY[NFASTBINS];

  /* Base of the topmost chunk -- not otherwise kept in a bin */
  mchunkptr top;//指向當前top chunk

  /* The remainder from the most recent split of a small request */
  mchunkptr last_remainder;

  /* Normal bins packed as described above */
  mchunkptr bins[NBINS * 2 - 2];

  /* Bitmap of bins */
  unsigned int binmap[BINMAPSIZE];//位圖,標記bins中是否存在內存塊

/* Arena被連成鏈表 */

  /* Linked list */
  struct malloc_state *next;

  /* Linked list for free arenas.  */
  struct malloc_state *next_free;

  /* Memory allocated from the system in this arena.  */
  INTERNAL_SIZE_T system_mem;
  INTERNAL_SIZE_T max_system_mem;
};

3.2堆(Heap)的分類與管理

堆,作為內存管理中的重要組成部分,就像是一個巨大的物資儲備庫,它為程序提供了動態分配內存的區域。在 Glibc 堆內存管理中,堆主要分為兩類,即主 Arena 的堆和子 Arena 的堆,它們各自有著獨特的特點和管理方式。

lang=c
/* 該數據結構只在子Arena中使用,用于記錄當前堆信息。 */
typedef struct _heap_info
{
  mstate ar_ptr; /* Arena for this heap. */ // 指向該堆所在的Arena
  struct _heap_info *prev; /* Previous heap. */ //由于一個子Arena管理多個堆,因此
  size_t size;   /* Current size in bytes. */ //當前堆分配給用戶使用的大小,剩余部分為預留區域
  size_t mprotect_size; /* Size in bytes that has been mprotected
                           PROT_READ|PROT_WRITE.  */ //從代碼來看,和size并無區別(本人意見)
  /* Make sure the following data is properly aligned, particularly
     that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of
     MALLOC_ALIGNMENT. */
  char pad[-6 * SIZE_SZ & MALLOC_ALIGN_MASK]; //用于對齊
} heap_info;

主 Arena 的堆是通過brk系統調用從操作系統獲取內存,它只有一個,就像一個大型的中央倉庫,位于進程地址空間的特定區域,從低地址向高地址增長。主 Arena 的堆在初始化時,其大小通常是一個較小的值,但隨著程序運行過程中對內存的不斷需求,它可以通過brk系統調用動態擴展。例如,當一個程序需要分配更多內存時,brk系統調用會將堆的末尾地址移動到所需內存塊的末尾地址,從而為程序提供新的內存空間。這就好比中央倉庫在物資不足時,可以通過擴建來增加存儲容量。主 Arena 的堆在內存管理中承擔著重要的角色,它是許多小型內存分配的主要來源,由于其內存分配和釋放的操作相對頻繁,因此需要高效的管理機制來確保內存的合理使用。

子 Arena 的堆則是通過mmap系統調用創建的,與主 Arena 的堆不同,子 Arena 的堆可以有多個,并且這些堆之間通過鏈表進行連接。這就像是多個分散的小型倉庫,每個倉庫都有自己獨立的管理方式。子 Arena 的堆通常用于滿足一些特殊的內存分配需求,或者在多線程環境下,為不同的線程提供獨立的內存分配空間,以減少線程之間的內存競爭。當一個子 Arena 的堆空間用盡時,會申請新的堆,并將其加入到鏈表中,就像小型倉庫物資不足時,會新建倉庫并與原有倉庫連接起來。

①堆的申請

第一類的堆無需申請,只是調用brk進行堆邊界的拓展即可。這里主要對第二類堆的申請進行說明。

  1. 堆的大小和對齊:第二類堆在申請時,總是mmap大小為HEAP_MAX_SIZE的內存,多出來的部分將作為預留空間,防止頻繁申請。并且使其首地址對齊于HEAP_MAX_SIZE,這可以方便找到堆的起始地址。
  2. 什么時候申請堆:在兩種情況會進行第二類堆的申請,第一種情況是在創建子Arena時,會相應地進行堆的申請作為該Arena的第一個堆;第二種情況是在原來申請的堆已經分配完畢時,會重新進行堆的申請,并將該堆和原來的堆通過鏈表連接起來。
  3. 堆的可用部分:只將用戶所需要的部分分配出去,并使用size記錄,剩下的部分作為預留。

②堆的釋放

這里堆的釋放是指glibc將申請的堆內存歸還給內核。

對于第一類堆,可以認為只有堆大小的縮減,當堆的頂部空閑的內存滿足一定條件時,可以通過brk將堆的邊界下移,top chunk指向地址不變,但大小變小了。

對于第二類堆,當一個堆中的內存已經完全被釋放時,就會將該該堆通過munmap歸還給內核,同時將top chunk重新指向上一個堆內的可用內存地址。

可以這么理解,堆由兩部分組成,一部分是已經分配出去的內存,另一部分是預留的內存(top,因為它總是存在于地址最高部分),而已經分配出去的內存一部分由free釋放,成為了空閑內存(內存碎片),由此除預留部分部分之外,分為兩種內存,空閑內存和已使用內存。

無論是主 Arena 的堆還是子 Arena 的堆,在內存的申請、釋放與管理過程中,都遵循著一定的機制。當程序通過malloc函數申請內存時,堆管理器會首先在堆中查找合適的空閑內存塊。如果找到大小合適的空閑內存塊,就會將其分配給程序使用,并將該內存塊標記為已分配狀態;如果沒有找到合適的空閑內存塊,堆管理器會根據情況從操作系統申請更多的內存,或者對已有的內存塊進行合并和整理,以滿足程序的內存需求。

而當程序通過free函數釋放內存時,堆管理器會將釋放的內存塊標記為空閑狀態,并嘗試將其與相鄰的空閑內存塊進行合并,以減少內存碎片化,提高內存利用率。這就像是在倉庫中,當需要領取物資時,會先查找倉庫中是否有合適的物資,若沒有則會申請新的物資;當歸還物資時,會將物資放回倉庫,并整理倉庫,使物資擺放更加整齊。

3.3內存塊(Chunk)的組織與操作

內存塊(Chunk)是 Glibc 堆內存管理中的基本單元,它就像是構成內存大廈的一塊塊基石,程序所使用的內存都是以 Chunk 為單位進行分配和管理的。了解 Chunk 的組織方式以及malloc和free操作內存塊的具體過程和原理,對于深入理解 Glibc 堆內存管理機制至關重要。

圖片

在堆中,Chunk 按照一定的規則進行組織。每個 Chunk 都包含了一些元數據,用于描述該 Chunk 的狀態和屬性。在 64 位系統中,一個典型的 Chunk 結構如下:

struct malloc_chunk {
    INTERNAL_SIZE_T prev_size; // 前一個Chunk的大小(如果前一個Chunk是空閑的)
    INTERNAL_SIZE_T size;      // 當前Chunk的大小,包括頭部和數據部分,并且包含一些標志位
    struct malloc_chunk* fd;   // 雙向鏈表指針,指向下一個空閑Chunk(僅當Chunk空閑時有效)
    struct malloc_chunk* bk;   // 雙向鏈表指針,指向前一個空閑Chunk(僅當Chunk空閑時有效)
    // 對于大內存塊,還會有以下兩個指針,用于快速查找不同大小的Chunk
    struct malloc_chunk* fd_nextsize; 
    struct malloc_chunk* bk_nextsize; 
};

prev_size字段用于記錄前一個 Chunk 的大小,當且僅當前一個 Chunk 是空閑狀態時,這個字段才是有效的,它為內存合并提供了重要的信息。size字段則記錄了當前 Chunk 的大小,這個大小包括了 Chunk 頭部的大小以及用戶數據部分的大小,并且在size字段的低 3 位中,還包含了一些標志位,用于表示 Chunk 的狀態,如是否是從mmap映射區分配的(M標志位)、前一個 Chunk 是否被使用(P標志位)以及是否屬于非主分配區(N標志位)。

fd和bk指針則是用于將空閑的 Chunk 組織成雙向鏈表,當一個 Chunk 被釋放時,它會被插入到相應的空閑鏈表中,以便后續的內存分配操作能夠快速找到合適的空閑 Chunk。而fd_nextsize和bk_nextsize指針則主要用于大內存塊的管理,它們可以幫助快速定位到不同大小的空閑 Chunk,提高大內存塊分配和釋放的效率。

當程序調用malloc函數申請內存時,malloc會按照一定的策略在堆中查找合適的 Chunk。首先,它會檢查請求的內存大小,如果請求的內存大小小于一個閾值(通常稱為max_fast),malloc會優先在fast bins中查找合適的 Chunk。fast bins是一種特殊的空閑鏈表,用于管理較小的內存塊,它采用單向鏈表結構,并且后進先出(FILO)的原則,這樣可以快速地分配和釋放小內存塊,提高內存分配的效率。如果在fast bins中沒有找到合適的 Chunk,malloc會繼續在small bins和large bins中查找。

small bins用于管理中等大小的內存塊,其中相同大小的 Chunk 被組織在同一個雙向循環鏈表中;large bins則用于管理較大的內存塊,每個large bins鏈表中保存的是一組大小范圍相近的 Chunk,并且這些 Chunk 按照大小從大到小排序。在查找過程中,如果找到大小合適的 Chunk,malloc會將其從空閑鏈表中移除,并根據需要對 Chunk 進行分割,將剩余的部分重新插入到合適的空閑鏈表中。

如果在所有的空閑鏈表中都沒有找到合適的 Chunk,malloc會嘗試使用top chunk。top chunk是位于堆頂部的一個空閑 Chunk,當其他空閑鏈表中沒有合適的內存塊時,malloc會從top chunk中分割出一部分來滿足內存請求,如果top chunk的大小小于請求的內存大小,malloc會通過系統調用(brk或mmap)向操作系統申請更多的內存。

當程序調用free函數釋放內存時,free會將釋放的 Chunk 標記為空閑狀態,并嘗試將其與相鄰的空閑 Chunk 進行合并,以減少內存碎片化。如果釋放的 Chunk 大小小于max_fast,它會被直接插入到fast bins中;如果大于max_fast,則會被插入到unsorted bin中。unsorted bin是一個臨時存放未整理 Chunk 的鏈表,后續malloc在查找內存塊時,會對unsorted bin中的 Chunk 進行整理,將它們移動到合適的small bins或large bins中。在合并 Chunk 時,free會根據prev_size和size字段中的標志位,判斷相鄰的 Chunk 是否空閑,如果相鄰的 Chunk 也是空閑的,則會將它們合并成一個更大的空閑 Chunk,然后再將其插入到相應的空閑鏈表中。

四、堆內存管理的分配

glib中堆內存分配的基本思路就是,首先找到本線程的Arena,然后優先在Arena對應的回收箱中尋找合適大小的內存,在內存箱中所有內存塊均小于所需求的大小,那么就會去top chunk分割,但是如果top chunk的大小也不足夠,此時不一定要拓展top,檢查所需的內存是否大于128k,若大于,則直接使用系統調用mmap分配內存,如果小于,就進行top chunk的拓展,即堆的拓展,拓展完成后,從top chunk中分配內存,剩余部分成為新的top chunk。

4.1 malloc函數

malloc 函數是 C 語言標準庫中用于動態內存分配的核心函數,其函數原型為:void* malloc(size_t size);。在這個原型中,size參數表示需要分配的內存塊的字節數,它是一個無符號整數類型(size_t),這意味著我們可以根據實際需求,精確地指定所需內存的大小。

malloc 函數的主要功能就是從堆內存中分配一塊指定大小的連續內存空間,并返回一個指向該內存塊起始地址的指針。這個返回的指針類型是void*,也就是無類型指針。這是因為 malloc 函數在分配內存時,并不知道這塊內存將來會被用于存儲什么類型的數據,所以它返回一個通用的無類型指針,需要我們在使用時將其強制轉換為實際所需的數據類型指針。例如,如果我們需要分配一塊內存來存儲整數,就需要將 malloc 返回的指針轉換為int*類型;如果要存儲字符,就轉換為char*類型。

(1)分配機制

當程序調用 malloc 函數請求分配內存時,其背后的分配機制涉及到操作系統與程序之間的協同工作。操作系統為了有效地管理堆內存,通常會維護一個空閑內存鏈表,這個鏈表就像是一個記錄著所有空閑 “房間”(內存塊)的清單。鏈表中的每個節點都代表著一塊空閑的內存區域,節點中包含了該內存塊的大小、前后指針等信息,以便操作系統能夠快速地查找和管理這些空閑內存。

當 malloc 函數被調用時,操作系統會按照一定的算法,通常是首次適應算法、最佳適應算法或最差適應算法等,開始遍歷這個空閑內存鏈表。以首次適應算法為例,操作系統會從鏈表的頭部開始,依次檢查每個空閑內存塊,尋找第一個大小大于或等于所需分配大小size的內存塊。一旦找到這樣的內存塊,操作系統就會將其從空閑鏈表中移除,并根據需要對該內存塊進行分割。如果找到的空閑內存塊比請求的size大,那么操作系統會將多余的部分重新插入到空閑鏈表中,以便后續的內存分配請求使用。而分割出來的正好滿足size大小的內存塊,就會被標記為已分配,并返回其起始地址給程序,這個地址就是 malloc 函數的返回值。通過這樣的方式,malloc 函數能夠在堆內存中靈活地為程序分配所需的內存空間,以滿足各種動態內存需求。

(2)示例代碼

下面通過一段簡單的 C 語言代碼示例,來展示 malloc 函數的具體用法。假設我們要動態分配一個包含 10 個整數的數組,并對其進行初始化和輸出:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr;
    int n = 10;

    // 使用malloc分配內存,為n個整數分配空間
    arr = (int *)malloc(n * sizeof(int));

    // 檢查內存分配是否成功
    if (arr == NULL) {
        printf("內存分配失敗\n");
        return 1;
    }

    // 初始化數組
    for (int i = 0; i < n; i++) {
        arr[i] = i + 1;
    }

    // 輸出數組內容
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // 釋放內存,避免內存泄漏
    free(arr);

    return 0;
}

4.2 free函數

free 函數與 malloc 函數緊密配合,是 C 語言中用于釋放動態分配內存的關鍵函數。其函數原型為:void free(void *ptr);,這里的ptr參數是一個指向先前通過 malloc、calloc 或 realloc 等函數動態分配的內存塊的指針。free 函數的主要功能就是將ptr所指向的內存塊歸還給系統,使其重新成為可供分配的空閑內存,以便后續其他內存分配請求使用。

(1)釋放機制

當程序調用 free 函數釋放內存時,其內部的釋放機制如下:free 函數首先會根據傳入的指針ptr,找到對應的內存塊。在 malloc 分配內存時,除了分配用戶請求大小的內存空間外,還會在該內存塊的頭部或其他特定位置,記錄一些額外的管理信息,如內存塊的大小等。free 函數通過這些管理信息,能夠準確地確定要釋放的內存塊的邊界和大小。然后,free 函數會將該內存塊標記為空閑狀態,并將其重新插入到操作系統維護的空閑內存鏈表中。

如果相鄰的內存塊也是空閑狀態,free 函數通常會將它們合并成一個更大的空閑內存塊,這一過程被稱為內存合并。內存合并可以有效地減少內存碎片的產生,提高內存的利用率。例如,在一個頻繁進行內存分配和釋放的程序中,如果不進行內存合并,隨著時間的推移,內存中可能會出現大量零散的小空閑內存塊,這些小內存塊由于無法滿足較大的內存分配請求,而導致內存資源的浪費。通過內存合并,這些相鄰的小空閑內存塊可以合并成一個較大的空閑內存塊,從而提高內存的使用效率。

(2)示例代碼

接著上面 malloc 函數的示例代碼,我們來看一下 free 函數的使用:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *arr;
    int n = 10;

    // 使用malloc分配內存,為n個整數分配空間
    arr = (int *)malloc(n * sizeof(int));

    // 檢查內存分配是否成功
    if (arr == NULL) {
        printf("內存分配失敗\n");
        return 1;
    }

    // 初始化數組
    for (int i = 0; i < n; i++) {
        arr[i] = i + 1;
    }

    // 輸出數組內容
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // 釋放內存,避免內存泄漏
    free(arr);
    // 將指針置空,避免懸空指針
    arr = NULL;

    return 0;
}

在這段代碼中,當我們使用 malloc 函數分配內存并完成對數組的操作后,調用 free (arr) 來釋放之前分配的內存。需要特別注意的是,在調用 free 函數之后,我們將指針arr賦值為NULL 。這是一個非常重要的操作,因為如果不將指針置空,arr就會成為一個懸空指針(Dangling Pointer)。懸空指針指向的是一塊已經被釋放的內存,繼續使用懸空指針進行內存訪問,會導致未定義行為,可能引發程序崩潰、數據損壞等嚴重問題。將指針置空后,就可以避免不小心對已釋放內存的訪問,提高程序的穩定性和安全性。

五、案例分析:GlibC Malloc for Exploiters 項目

5.1項目介紹

在安全研究的廣闊領域中,GlibC Malloc for Exploiters 項目宛如一顆璀璨的明星,為我們深入理解 glibc 堆內存管理機制以及開展安全研究提供了強大的助力。該項目可以說是對 GlibC 分配器進行了一次極為深入且全面的剖析,堪稱安全研究人員探索內存管理漏洞的有力工具。

當我們訪問其 GitHub Pages 站點,或者直接閱讀 Markdown 格式的原始內容時,就如同踏入了一座知識的殿堂。這里面詳細講解了 glibc 堆內存管理的諸多細節,還通過豐富的實戰演示,將抽象的概念具象化,讓我們能夠更加直觀地理解相關知識。不僅如此,項目還貼心地分享了作者在 Insomni'hack 會議上的演講視頻,為我們的學習之路提供了更為生動直觀的方式,使我們能夠從多個角度深入了解項目的核心內容。

5.2技術分析與應用

GlibC Malloc 作為 Linux 環境下被廣泛使用的內存分配器,其運作機制極其復雜且微妙。GlibC Malloc for Exploiters 項目就像一把精準的手術刀,深入到 GlibC 的內部,清晰地揭示了 malloc 與 free 函數是如何管理堆內存的,尤其是在那些易受攻擊的場景下,它們的行為模式更是被剖析得淋漓盡致。

通過逆向工程與實證分析的手段,該項目為我們提供了一系列深刻的洞見。這些洞見能夠幫助開發者和安全研究員更好地理解那些可能導致安全漏洞的關鍵環節。比如,在內存碎片化管理方面,項目詳細闡述了隨著程序不斷地進行內存分配和釋放操作,內存是如何逐漸碎片化的,以及這種碎片化對程序性能和安全性的影響。對于 bins 結構,它深入分析了不同類型的 bins(如 fast bins、small bins、large bins 等)是如何組織和管理內存塊的,以及在內存分配和釋放過程中,bins 結構是如何發揮作用的。還有雙鏈表的脆弱之處,項目也進行了詳細的探討,指出了雙鏈表在某些情況下可能出現的問題,如指針錯誤、鏈表遍歷異常等,這些問題都有可能被攻擊者利用,從而導致安全漏洞。

在實際應用場景中,GlibC Malloc for Exploiters 項目展現出了極高的價值。對于安全研究者而言,掌握 GlibC Malloc 的工作原理是構建防御機制與實施精準攻擊的基石。在進行安全審計時,研究人員可以借助該項目提供的知識和工具,對程序的內存分配和釋放操作進行細致的檢查,從而發現潛在的安全隱患。在漏洞挖掘方面,通過深入理解 glibc 堆內存管理機制,研究人員能夠更敏銳地捕捉到可能存在的漏洞,如堆溢出、釋放后重用等。在開發防御工具時,該項目的研究成果也能為工具的設計提供重要的參考,幫助開發出更有效的防御工具,提高系統的安全性。

在逆向工程和滲透測試中,這個項目同樣發揮著重要作用。它能夠幫助研究人員找到內存操作中的薄弱點,從而進行有效的 exploit 開發。在 CTF 比賽中,很多題目都涉及到堆溢出等漏洞的利用,了解 GlibC Malloc for Exploiters 項目所揭示的細節,能夠極大地提升選手對這些漏洞的利用效率,幫助選手在比賽中取得更好的成績。

責任編輯:武曉燕 來源: 深度Linux
相關推薦

2024-11-07 09:37:46

2009-10-22 17:39:34

CLR內存管理

2025-06-03 04:10:00

2009-09-02 09:23:26

.NET內存管理機制

2013-07-23 06:47:55

Android內存機制Android堆和棧Android開發學習

2010-07-23 09:34:48

Python

2013-09-29 15:11:46

Linux運維內存管理

2009-06-03 15:52:34

堆內存棧內存Java內存分配

2022-06-01 16:01:58

MySQL內存管理系統

2010-09-26 13:23:13

JVM內存管理機制

2021-03-08 09:00:00

Java編程內存

2025-04-09 05:22:00

2025-09-29 05:00:00

Linux線程棧內存

2025-01-14 10:09:43

硬中斷Linux系統

2011-06-29 17:20:20

Qt 內存 QOBJECT

2010-12-10 15:40:58

JVM內存管理

2020-11-08 14:32:01

JavaScript變量內存管理

2016-10-09 14:41:40

Swift開發ARC

2022-02-28 10:25:17

Python參數傳遞拷貝

2025-04-15 06:00:00

點贊
收藏

51CTO技術棧公眾號

51国产偷自视频区视频| 超碰中文字幕在线观看| 天天操天天干天天| 久久久噜噜噜| 北条麻妃99精品青青久久| 在线观看日本www| 国产黄大片在线观看| 久久精品欧美一区二区三区不卡| 国产精品普通话| 黄色在线观看免费| 国产欧美日韩视频在线| 欧美美女一区二区三区| 伊人性伊人情综合网| 精品日韩av一区二区| 国产亚洲精品网站| 国产素人视频在线观看| 久久一二三国产| 91精品美女在线| 中文字幕在线观看视频网站| 999视频精品| 亚洲国产成人一区| 色18美女社区| 日本少妇一区| 亚洲国产一区二区在线播放| 日韩欧美视频一区二区三区四区| 亚洲大尺度网站| 久久国产欧美日韩精品| 欧美一级大胆视频| 无套白嫩进入乌克兰美女| 都市激情亚洲综合| 亚洲成人免费av| 美女av免费观看| 永久免费av在线| 久久综合久久综合九色| 国产成人精品免费视频大全最热| 一级做a爱片性色毛片| 久久久精品日韩| 国内精品久久久久久中文字幕| 国产精品suv一区二区88| 亚欧洲精品视频在线观看| 欧美精品一区二区高清在线观看| 免费不卡av网站| 久久亚洲人体| 在线免费不卡视频| 国产日韩一区二区在线观看| gogo高清午夜人体在线| 亚洲国产wwwccc36天堂| 欧美另类videosbestsex日本| aaa在线观看| 久久精品亚洲一区二区三区浴池| 国产一区二区黄色| 婷婷五月综合久久中文字幕| 大白屁股一区二区视频| 成人欧美一区二区三区在线观看| 国产黄色片av| 丰满亚洲少妇av| 97夜夜澡人人双人人人喊| 国产视频手机在线| 国产一区二区三区四区五区美女| 91精品在线看| 精品国产av 无码一区二区三区 | 亚洲大片免费观看| 免费日韩精品中文字幕视频在线| 8x海外华人永久免费日韩内陆视频| 久久综合色综合| 亚洲伦伦在线| 欧美在线观看网址综合| 日本熟女毛茸茸| 秋霞午夜av一区二区三区| 国产日韩欧美自拍| a视频免费在线观看| 成人免费观看av| 精品国产乱码久久久久久蜜柚| 天天干天天操av| 久久亚洲精精品中文字幕早川悠里| 免费在线观看91| 成人18在线| 亚洲欧洲美洲综合色网| 隔壁人妻偷人bd中字| 91吃瓜在线观看| 91福利在线看| 91欧美一区二区三区| 日韩免费成人| 日韩精品在线观| 青青草华人在线视频| 中文字幕免费一区二区| 国内精品久久久久久中文字幕 | 欧美日韩国产综合视频在线观看 | 日韩第二十一页| 91精品国产欧美日韩| 国产女人18毛片水真多18| 国产传媒欧美日韩成人精品大片| www国产91| 国产在线一区视频| 热久久免费视频| 97se视频在线观看| 理论视频在线| 一区二区三区在线观看视频| 欧美日韩在线不卡视频| 国产精品久久免费视频| 亚洲黄色成人网| 日韩欧美在线视频播放| 国模大胆一区二区三区| 国产精品美女在线观看| 性一交一乱一乱一视频| 日本一区二区免费在线观看视频 | 久久精品日产第一区二区三区乱码 | 亚洲欧美电影| 日韩欧美资源站| 在线免费观看视频| 99视频在线精品国自产拍免费观看| 国产精品日韩一区| 黄色小视频免费观看| 国产精品久久久久影视| 你懂的av在线| 免费精品一区二区三区在线观看| 亚洲欧美一区二区精品久久久| 一区二区在线观看免费视频| 肉色丝袜一区二区| 国产另类自拍| 高h视频在线观看| 欧美性大战久久久久久久蜜臀 | 国产视频一区二区在线观看| 欧美日韩激情四射| 91丨精品丨国产| 在线丨暗呦小u女国产精品| 日韩三级视频在线播放| 国产一区二区福利| 宅男在线精品国产免费观看| 欧美动物xxx| 亚洲第一区中文99精品| www青青草原| 久久99精品国产麻豆不卡| 欧美日韩综合另类| 日韩深夜视频| 亚洲高清福利视频| 久久久久无码国产精品不卡| 国产在线精品视频| 一区二区成人国产精品| 黄色精品视频| 在线播放日韩精品| 中文人妻熟女乱又乱精品| 久久久久久久久久久黄色| 黄色一级片播放| 久久视频在线观看| 97视频在线观看视频免费视频 | 欧美一性一交| 97久久久久久| 婷婷五月综合激情| 狠狠操狠狠色综合网| 漂亮人妻被黑人久久精品| 亚洲国产专区| 精品亚洲一区二区三区四区五区高| av午夜在线观看| 亚洲福利视频在线| 特一级黄色大片| 91色视频在线| 热久久精品国产| 欧洲三级视频| 成人高h视频在线| a视频在线观看免费| 日韩视频在线你懂得| 久久艹精品视频| 成人的网站免费观看| 欧美日韩精品在线一区二区| 亚洲激情77| 国产v综合ⅴ日韩v欧美大片| 国产日韩精品在线看| 欧美蜜桃一区二区三区| 婷婷在线精品视频| 成人av第一页| 日韩av播放器| 色狮一区二区三区四区视频| 亚洲专区在线视频| 国产高潮在线| 在线观看不卡av| 国产农村妇女毛片精品| 亚洲国产视频一区| 国产一二三四五区| 国产在线看一区| 一女被多男玩喷潮视频| 成人亚洲一区二区| 98国产高清一区| 在线精品亚洲欧美日韩国产| 中文字幕欧美日韩在线| 性欧美8khd高清极品| 欧美色另类天堂2015| 激情无码人妻又粗又大| 岛国精品在线播放| 亚洲老女人av| 亚洲精品日韩久久| 亚洲国产精品久久久久婷婷老年 | 日本不卡不码高清免费观看| 中国黄色录像片| 色狼人综合干| 96国产粉嫩美女| 亚洲校园激情春色| 久久亚洲精品中文字幕冲田杏梨| 欧美 日韩 国产 在线| 欧美亚洲免费在线一区| 久久精品久久精品久久| 国产精品天干天干在线综合| 国产精品久久久久久久无码| 久久超碰97人人做人人爱| 精品无码一区二区三区在线| 色欧美自拍视频| 欧美成人第一区| 亚洲超碰在线观看| 国产免费一区视频观看免费 | 四虎成人av| 精品国产一区二区三区四区精华 | 99thz桃花论族在线播放| 伊人青青综合网站| 天天射天天色天天干| 69久久99精品久久久久婷婷| 国产又粗又爽视频| 亚洲一二三四区不卡| 中文国语毛片高清视频| 国产亚洲女人久久久久毛片| japanese在线观看| 国产一区二区影院| jizz欧美性11| 天堂成人免费av电影一区| 很污的网站在线观看| 欧美.www| 国产精品h视频| 成人午夜av| 日韩欧美国产二区| 西瓜成人精品人成网站| 精品国产乱码久久久久久88av | 九九视频免费看| 亚洲欧洲日本在线| 一级免费黄色录像| 国产精品人成在线观看免费| 人人人妻人人澡人人爽欧美一区| 97久久精品人人做人人爽| 绯色av蜜臀vs少妇| 国产乱人伦精品一区二区在线观看 | 亚洲一区资源| 97在线视频免费观看| 俺来俺也去www色在线观看| 色综合久综合久久综合久鬼88| 日本中文字幕在线2020| 日韩在线激情视频| 欧美性天天影视| 精品国偷自产在线| 老司机在线视频二区| 日韩中文字幕在线| 黄色小网站在线观看| 精品国产拍在线观看| av在线之家电影网站| 伊人av综合网| 免费高清在线观看| 欧美巨乳美女视频| 色网在线观看| 性色av香蕉一区二区| 人成在线免费网站| 国产成人精品视频在线观看| 日韩久久一区二区三区| 国产精品香蕉在线观看| 欧美爱爱视频| 91av一区二区三区| 国产精品18hdxxxⅹ在线| 国产一区二区中文字幕免费看| 欧美黑白配在线| 欧洲成人一区二区| 婷婷色综合网| 97视频在线免费| 久久激情视频| 中文字幕永久有效| 国产成人在线免费观看| 国产视频久久久久久| 久久久久久久久久久久久久久99 | 91精品天堂福利在线观看| 黄色小视频大全| 一区二区激情| 欧美成年人视频在线观看| 国产酒店精品激情| 国产精品福利导航| 国产精品女人毛片| 久久久91视频| 色欧美88888久久久久久影院| 亚洲图片小说视频| 久久三级毛片| 久久九九全国免费精品观看| www在线免费观看视频| 97精品国产91久久久久久| 小黄鸭精品aⅴ导航网站入口| 国产日韩亚洲欧美| 日韩深夜影院| 中文字幕一区二区三区精彩视频| 极品日韩av| 日韩大片一区二区| 不卡一区二区中文字幕| 黑人と日本人の交わりビデオ| 亚洲综合丝袜美腿| 亚洲视屏在线观看| 亚洲精品一区二区三区在线观看| 国产1区2区3区在线| 欧美激情精品久久久久久黑人 | 免费黄色在线| 欧美有码在线视频| 美女精品视频在线| 日韩中文字幕av在线| 在线播放亚洲| 亚洲一区精品视频在线观看| 久久综合九色综合97婷婷女人 | 秘密基地免费观看完整版中文| 国产亚洲欧洲一区高清在线观看| 青春草免费视频| 精品婷婷伊人一区三区三| 人妻精品无码一区二区| 久久精品在线播放| 日韩欧美少妇| 麻豆av一区二区三区久久| 欧美va天堂在线| 日韩av片专区| 国产欧美一区二区精品婷婷| 亚洲另类欧美日韩| 精品人在线二区三区| 麻豆传媒视频在线| 国产精品美女无圣光视频| 香蕉人人精品| 日本欧美黄色片| 成人性生交大片免费看中文| av激情在线观看| 51久久夜色精品国产麻豆| 国产系列在线观看| 日本精品久久中文字幕佐佐木| 开心激情综合| 欧美国产视频一区| 风间由美性色一区二区三区| 亚洲综合久久av一区二区三区| 91福利国产成人精品照片| 亚洲av电影一区| 国内精品免费午夜毛片| 999精品视频在这里| 国产精品无码电影在线观看| 国产黄色精品网站| 劲爆欧美第一页| 日韩欧美亚洲一区二区| 四虎影视成人| 99久久伊人精品影院| 欧美激情日韩| av电影中文字幕| 亚洲午夜免费视频| 午夜小视频免费| 欧美亚洲日本网站| 欧美女王vk| 天堂社区在线视频| 国产精品久久久久久一区二区三区| 中日精品一色哟哟| 日韩在线播放av| 激情不卡一区二区三区视频在线| 中文字幕av久久| 成人免费视频一区| 免费黄色网址在线| 中文字幕国产日韩| 永久免费观看精品视频| 国产1区2区3区中文字幕| 成人性视频免费网站| 四虎成人永久免费视频| 亚洲人成伊人成综合网久久久 | 999视频在线观看| 激情av一区| 中文字幕av网址| 欧美性三三影院| 国产婷婷视频在线| 国产日韩一区二区三区| 国产精品视区| 中字幕一区二区三区乱码| 欧美疯狂性受xxxxx喷水图片| 成人免费在线| 韩国成人动漫在线观看| 久久最新视频| 日本午夜在线观看| 亚洲国产成人久久综合| 99久久婷婷国产综合精品首页| 福利网在线观看| 91在线视频在线| 亚洲熟妇av乱码在线观看| 欧美精品一区二区免费| 日韩精品亚洲aⅴ在线影院| 亚洲国产高清av| 亚洲国产精品影院| 国产福利在线看| 成人精品水蜜桃| 老**午夜毛片一区二区三区| 日本 欧美 国产| 日韩精品免费视频| 日韩深夜福利网站| 国产精品无码av在线播放| 中文字幕制服丝袜成人av | 国产亚洲欧美日韩一区二区| 99久久这里有精品| 欧美一级黄色影院| 亚洲一区二区偷拍精品| 免费网站免费进入在线| 欧美精品久久久| 国产sm精品调教视频网站|