1. 程式人生 > >C++程式的記憶體佈局

C++程式的記憶體佈局

    對任何一個普通C++程式來講,它都會涉及到5種不同的資料段。常用的幾個資料段種包含有“程式程式碼段”、“程式資料段”、“程式堆疊段”等。不錯,這幾種資料段都在其中,但除了以上幾種資料段之外,程序還另外包含兩種資料段。下面我們來簡單歸納一下程序對應的記憶體空間中所包含的5種不同的資料區。


程式碼段:程式碼段是用來存放可執行檔案的操作指令,也就是說是它是可執行程式在記憶體種的映象。程式碼段需要防止在執行時被非法修改,所以只准許讀取操作,而不允許寫入(修改)操作——它是不可寫的。

資料段:資料段用來存放可執行檔案中已初始化全域性變數,換句話說就是存放程式靜態分配的變數和全域性變數。

BSSBSS段包含了程式中未初始化全域性變數,在記憶體中bss段全部置零。

堆(heap:堆是用於存放程序執行中被動態分配的記憶體段,它大小並不固定,可動態擴張或縮減。當程序呼叫malloc/new等函式分配記憶體時,新分配的記憶體就被動態新增到堆上(堆被擴張);當利用free等函式釋放記憶體時,被釋放的記憶體從堆中被剔除(堆被縮減)

:棧是使用者存放程式臨時建立的區域性變數,也就是說我們函式括弧“{}”中定義的變數(但不包括static宣告的變數,static意味這在資料段中存放變數)。除此以外在函式被呼叫時,其引數也會被壓入發起呼叫的程序棧中,並且待到呼叫結束後,函式的返回值也回被存放回棧中。由於棧的先進先出特點,所以棧特別方便用來儲存

/恢復呼叫現場。從這個意義上將我們可以把堆疊看成一個臨時資料寄存、交換的記憶體區。


    我們要知道,棧中存放的是一個個被調函式所對應的堆疊幀,當函式fun1被呼叫,則fun1的堆疊幀入棧,fun1返回時,fun1的堆疊幀出棧。什麼是堆疊幀呢,堆疊幀其實就是儲存被調函式返回時下一條執行指令的指標、主調函式的堆疊幀的指標、主調函式傳遞給被調函式的實參(如果有的話)、被調函式的區域性變數等資訊的一個結構。

    首先,我們要說明的是如何區分每個堆疊幀,或者說,如何知道我現在在使用哪個堆疊幀。和棧密切相關的有2個暫存器,一個是ebp,一個是esp,前者可以叫作棧基址指標,後者可以叫棧頂指標。對於一個堆疊幀來說,

ebp也叫堆疊幀指標,它永遠指向這個堆疊幀的某個固定位置(見上圖),所以可以根據ebp來表示一個堆疊幀,可以通過對ebp的偏移加減,來在堆疊幀中來來回回的訪問。esp則是隨著pushpop而不斷移動。因此根據esp來對堆疊幀進行操作。
再來講一下上圖,一個堆疊幀的最頂部,是實參,然後是
return address,這個值是由主調函式中的call命令在call呼叫時自動壓入的,不需要我們關心,previousframe pointer,就是主調函式的堆疊幀指標,也就是主調函式的ebp值。ebp偏移為正的都是被調函式的區域性變數。


相關推薦

C++/C程式記憶體佈局及函式棧結構

一:系統的程式佈局圖: 二、詳解: 程式空間: 包括.txt程式碼段,.data資料段, .bss段,堆段,棧段。程式的地址從低往高。堆空間增長方向從低地址往高地址增長。 棧空間從高地址往低地址方向增長。從左往右方向為單位元組增長方向。

c++物件記憶體佈局模型

轉自:點選開啟連結 首先介紹一下C++中有繼承關係的類物件記憶體的佈局:  在C++中,如果類中有虛擬函式,那麼它就會有一個虛擬函式表的指標__vfptr,在類物件最開始的記憶體資料中。之後是類中的成員變數的記憶體資料。  對於子類,最開始的記憶體資料記錄著父類物件的拷貝

Unix下C程式記憶體洩漏檢測工具Valgrind安裝與使用

                Valgrind是一款用於記憶體除錯、記憶體洩漏檢測以及效能分析的軟體開發工具。 Valgrind的最初作者是Julian Seward,他於2006年由於在開發Valgrind上的工作獲得了第二屆Google-O'Reilly開原始碼獎。 Valgrind遵守GNU通用公共許

c程式記憶體分佈

        由C語言程式碼(文字檔案)形成可執行程式(二進位制檔案),需要經過編譯-彙編-連結三個階段。編譯過程把C語言文字檔案生成彙編程式,彙編過程把彙編程式形成二進位制機器程式碼,連結過

C程式記憶體管理

C程式的記憶體管理 熟悉Java語言的肯定知道,Java中記憶體管理是由虛擬機器幫助我們完成的,在C/C++中可不是這樣,程式設計師需要自己去分配和回收記憶體空間。本文記錄了C程式可執行檔案的儲存結構、在記憶體中的儲存結構等方面的內容。以下C程式所使用的編譯器版本是GCC

c/c++程式記憶體劃分使用筆記

從以上知識可知,棧是系統提供的功能,特點是快速高效,缺點是有限制,資料不靈活;而堆是函式庫提供的功能,特點是靈活方便,資料適應面廣泛,但是效率有一定降低。棧是系統資料結構,對於程序/執行緒是唯一的;堆是函式庫內部資料結構,不一定唯一。不同堆分配的記憶體無法互相操作。棧空間分靜態分配和動態分配兩種。靜態分配是編

Linux平臺下如何檢測、除錯C/C++程式記憶體洩漏

1."記憶體洩露"包括堆記憶體洩露、棧記憶體洩露。根據記憶體的型別,又分為:記憶體申請、釋放,控制代碼的開啟與關閉問題。 2.容易忽視的是棧上的記憶體洩露,嚴格來講是申請的記憶體超過執行緒棧空間大小(預設為1MB)。棧上的記憶體(即區域性變數)是不需要釋放的,函式返回自動出棧(釋放)。若某時刻超過執行緒棧

C++物件記憶體佈局

想要研究物件的記憶體佈局必須要去對應的記憶體去檢視。 一、兩種檢視物件記憶體的方法 先選擇我們寫的C++原始檔,右鍵選擇屬性,在彈出的對話方塊中選擇左側的C/C++->命令列,然後在其他選項這裡寫上/d1reportAllClassLayout,它可以看到所有相關類

c++常見面試題-C/C++程式記憶體分配情況

1.由C/C++編譯的程式佔用的記憶體分為以下幾個部分 1、棧區(stack)—   由編譯器自動分配釋放 ,存放為執行函式而分配的區域性變數、函式引數、返回資料、返回地址等。其操作方式類似於資料結構中的棧。 2、堆區(heap) —   一般由程式設計師分配釋放, 若程式

C++程式記憶體洩露

一、記憶體洩露 1、delete銷燬物件時,不會free掉成員變數申請的記憶體區域 (1)銷燬物件時,如果解構函式沒有釋放成員變數指向的記憶體區域,則會造成記憶體洩露 (2)使用STL模板類,delete模板物件指標時,不會自動free模板類成員申請的記憶體區域 示例

C++程式執行時記憶體佈局之----------區域性變數,全域性變數,靜態變數,函式程式碼,new出來的變數

宣告兩點: (1)開發測試環境為VS2010+WindowsXP32位; (2)記憶體佈局指的是虛擬記憶體地址,不是實體地址。   1.測試程式碼 #include <iostream> using namespace std; int g_int_a; i

C程式(程序)的記憶體佈局

C程式(程序)的記憶體佈局 #include <stdio.h> const int a = 10; //全域性常量a int main(void) {   const int b = 20; //區域性常量b   int* pa =

C++程式記憶體佈局

    對任何一個普通C++程式來講,它都會涉及到5種不同的資料段。常用的幾個資料段種包含有“程式程式碼段”、“程式資料段”、“程式堆疊段”等。不錯,這幾種資料段都在其中,但除了以上幾種資料段之外,程序還另外包含兩種資料段。下面我們來簡單歸納一下程序對應的記憶體空間中所包

7.6. 一個C程式記憶體佈局(memory layout)

7.6.一個C程式的記憶體佈局(memory layout)一個C程式一直以來都是由以下5個段(pieces)組成: 程式碼段(text segment):存放CPU執行的機器指令(machine instructions)。通常情況下,程式碼段是可共享的,使其可共享的目的是

C++程式中的記憶體佈局

記憶體分配: 1、棧區(stack)— 由編譯器自動分配釋放 ,存放區域性變數、臨時變數、引數值。其操作方式類似於資料結構中的棧。 2、堆區(heap) — 一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由OS回收 。 3、全域性區(靜態區)(stat

C/C++程式記憶體分配

     轉:https://blog.csdn.net/zcyzsy/article/details/69788884             C/C

C++物件模型之記憶體佈局(3)

轉載地址:https://mp.weixin.qq.com/s/dTyAC2IQ50c9nmQGOC0c2A   經過兩天的摸索,今天終於搞清楚C++物件模型.前兩篇C++物件模型之記憶體佈局(2)C++物件模型之記憶體佈局(1)(請戳我)已經講解了單繼承,多重繼承和多繼承的物件模

C++物件模型之記憶體佈局(2)

轉載地址:https://mp.weixin.qq.com/s/UQhTAXIHffN3Now4_utb6g   在C++物件模型之記憶體佈局(1)一文中分別講了無多型和有多型時單繼承的物件記憶體佈局,這篇文章將深入講解多重繼承和多繼承.   多重繼承 &nb

C++物件模型之記憶體佈局(1)

轉載地址: https://mp.weixin.qq.com/s/LMJ4Hsa1hmued2egk9uWMQ   如果想學習在linux或者在linux平臺下開發,學習C/或C++是非常好的選擇.俗話說,術業有專攻,學一門技術,就儘量學得深,也可以作為行走江湖,混口飯吃的一項本領

C++ 繼承中的記憶體佈局

今天在網上看到了一篇寫得非常好的文章,是有關c++類繼承記憶體佈局的。看了之後獲益良多,現在轉在我自己的部落格裡面,作為以後複習之用。 ——談VC++物件模型 (美)簡.格雷 程化    譯 譯者前言 一個C++程式設計師,想要進一步提升技術水平的話