為了說明這個問題,我們首先來看看乙個例子:
char *returnstr()
char *returnarr()
void main()
這是什麼原因呢?
我們知道:字串是被當做字元陣列來處理的。所以字元陣列名就相當於指向首位址的指標。那麼
char *s = "abcdef"; 和
char a = "abcdef";
這兩種表示式似乎是一樣的,可是為什麼程式結果會不一樣呢?
原因:第一種表示式, char *s = "abcdef";
指標s是區域性變數,他的作用域是函式returnstr
內。它將其指向的位址返回,返回之後s即被銷毀,慶幸s指向的位址被返回了回來。最終列印正確。
第二種表示式,char a = "abcdef";
那麼我們會問第二種與第一種的區別在哪,為何錯?原因就是第一種指標s雖然是區域性變數,被分配在棧空間,作用域是函式內部,但其指向的內容"abcdef"是常量,被分配在程式的常量區。直到整個程式結束才被銷毀。而第二種,s是一陣列,分配到棧空,"abcdef"作為陣列各個元素被放到陣列中,一旦函式退出,棧中這塊記憶體就被釋放。雖然返回乙個位址,可是已經失去它的意義了。所以,這裡編譯器也提示我們返回了乙個區域性變數。
這裡涉及到了 記憶體分配的問題。
乙個由c/c++編譯的程式占用的記憶體分為以下幾個部分:
1、棧區(stack): 由編譯器自動分配釋放管理。函式呼叫,存放函式的引數值,儲存函式的返回位址,區域性變數的值等。其操作方式類似於資料結構中的棧。
2、堆區(heap): 一般由程式設計師分配釋放管理。若程式設計師不釋放,程式結束時可能由os**。推薦要自己釋放,否則會發生記憶體洩露。(
注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶)
3、未初始化資料段(bbs) :
bss是英文block started by symbol的簡稱,屬於靜態記憶體分配。存放未初始化的靜態變數或全域性變數。
程式結束後由系統釋放。
4、初始化資料段(data) :資料段又分為讀寫資料段和唯讀資料段。
|—— 唯讀資料段:const修飾的全域性變數或區域性變數。程式結束後由系統釋放
|—— 讀寫資料段:已初始化的全域性變數或區域性變數。
5、**區(text) :存放程式的二進位制**。**段是唯讀的,可被多個程序共享。
C語言的記憶體分配 參考
char returnstr char returnarr int main 為了說明這個問題,我們首先來看看上面例子 這是什麼原因呢?char s abcdef 和 char a abcdef 這兩種表示式似乎是一樣的,可是為什麼程式結果會不一樣呢?原因 第一種表示式,char s abcdef ...
C語言的記憶體分配
文章一 c語言的記憶體分配模型 1 程式 區 存放函式體的二進位制 2 全域性區資料區 全域性資料區劃分為三個區域。全域性變數和靜態變數的儲存是放在一塊的,初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。常量資料存放在另乙個區域裡。這些資料在程式結...
C語言記憶體分配
c語言的記憶體分配主要有5個區域 1 棧區 在執行函式時,函式內的區域性變數 不包括static變數 函式返回值的儲存單元在棧區上建立。函式執行結束時這些儲存單元自動被釋放。棧區記憶體分配運算內置於處理器的指令集中,效率很高,但分配的記憶體容量有限。2 堆區 程式在執行的時候用malloc call...