1. 程式人生 > >C語言 記憶體分配和static關鍵字

C語言 記憶體分配和static關鍵字

C語言記憶體分配機制 (1)程式碼區(text segment)。.text程式碼區指令根據程式設計流程依次執行,對於順序指令,則只會執行一次(每個程序),如果反覆,則需要使用跳轉指令,如果進行遞迴,則需要藉助棧來實現。程式碼區的指令中包括操作碼和要操作的物件(或物件地址引用)。如果是立即數(即具體的數值,如5),將直接包含在程式碼中;如果是區域性資料,將在棧區分配空間,然後引用該資料地址;如果是BSS區和資料區,在程式碼中同樣將引用該資料地址。 (2)全域性初始化資料區/靜態資料區(Data Segment)。只初始化一次。包含程式中需明確賦初始值的變數,儲存已經初始化的全域性變數 (3)未初始化資料區(BSS).bbs段在程式開始執行之前,核心將此段中的資料初始化為0或空指標,儲存未初始化的全域性變數(注意:即使是賦值為0也是未初始化!) (4)棧區(stack)。由編譯器自動分配釋放,存放函式的引數值、區域性變數的值等。其操作方式類似於資料結構中的棧。每當一個函式被呼叫,該函式返回地址和一些關於呼叫的資訊,比如某些暫存器的內容,被儲存到棧區。然後這個被呼叫的函式再為它的自動變數和臨時變數在棧區上分配空間,這就是C實現函式遞迴呼叫的方法。每執行一次遞迴函式呼叫,一個新的棧框架就會被使用,這樣這個新例項棧裡的變數就不會和該函式的另一個例項棧裡面的變數混淆。 (5)堆區(heap)。用於動態記憶體分配。堆在記憶體中位於bss區和棧區之間。一般由程式設計師分配和釋放,若程式設計師不釋放,程式結束時有可能由OS回收。 在這裡插入圖片描述

為什麼需要把記憶體分成多個段? 一個程序在執行過程中,程式碼是根據流程依次執行的,只需要訪問一次,當然跳轉和遞迴有可能使程式碼執行多次,而資料一般都需要訪問多次,因此單獨開闢空間以方便訪問和節約空間。 臨時資料及需要再次使用的程式碼在執行時放入棧區中,生命週期短。 全域性資料和靜態資料有可能在整個程式執行過程中都需要訪問,因此單獨儲存管理。 堆區由使用者自由分配,以便管理。 詳細參考:https://www.cnblogs.com/wanghuaijun/p/6509016.html

static關鍵字的作用 C語言:(在普通變數已有屬性上增加static的屬性作用) 1.限制變數或函式的作用域,static修飾全域性變數或者的時候,將函式和變數的作用域限定與原始檔,其他檔案不能訪問函式和變數,即便是extern外部宣告也調用不了。增加資料的安全性。(與普通全域性變數的區別)

2.定義變數的生命週期。由static修飾的變數,其儲存型別為全域性靜態區,變數在程式的整個執行過程中不會被銷燬,並且只會被初始化1次。(主要是區域性變數生命週期延長)

C++: 具有C語言裡的全部特性。 類中,static可以用來修飾靜態資料成員和靜態成員方法 靜態資料成員 (1)靜態資料成員可以實現多個物件之間的資料共享,它是類的所有物件的共享成員,它在記憶體中只佔一份空間,如果改變它的值,則各物件中這個資料成員的值都被改變。 (2)靜態資料成員是在程式開始執行時被分配空間,到程式結束之後才釋放,只要類中指定了靜態資料成員,即使不定義物件,也會為靜態資料成員分配空間。 (3)靜態資料成員可以被初始化,但是隻能在類體外進行初始化,若為對靜態資料成員賦初值,則編譯器會自動為其初始化為0 (4)靜態資料成員既可以通過物件名引用,也可以通過類名引用。

靜態成員函式 (1)靜態成員函式和靜態資料成員一樣,他們都屬於類的靜態成員,而不是物件成員。 (2)非靜態成員函式有this指標,而靜態成員函式沒有this指標。 (3)靜態成員函式主要用來訪問靜態資料成員而不能訪問非靜態成員。