關於字串常量在記憶體中的生命週期

2021-07-23 18:35:38 字數 2242 閱讀 8318

字串char *s="hello"; 與char s="hello";,看似都是將hello字串的位址賦值給指標 *p。

但是前面乙個表示式是字串常量的位址賦值給指標 該指標指向的字串中的字元是不允許被更改的。

而後面乙個表示式是將該字串的每乙個字元賦值給陣列,該指標指向的陣列的首位址,而陣列成員是變數,因此可以允許被更改賦值。

關於以上個問題我們就不做詳細討論了,網上有很多文章關於這個問題的。主要討論由以上這個問題引出來的關於字串常量在記憶體中存在生命週期的的問題。

問題如下:

假如 char *s0="hello";

s0="world";

就是說如果開始s0指標指向「hello」這個字串這個常量的位址,但是當s0指標指向了「world」符串的時候那麼「hello」這個字串在記憶體中的是否會被釋放掉,還是會一直存在記憶體中,直到程式結束。

我們不妨先試著寫幾行**,通過執行結果來進行分析:

案例 一:

**:#include

int main()

執行結果:

三個指標變數的指向的位址都是相同的,如圖

分析:通過執行結果我們可以看出,賦給不同字元指標的相同的字串,所有的指標都指向了相同的位址。

但是案例一由於三個指標變數都在同乙個函式,因此不能看出其生命週期,但是可以為下面的案例解釋做好鋪墊。

案例二:

**:#include

char *s0="hello";

void a()

void b()

int main()

執行結果:

四個字元指標變數指向的位址還是一樣的。

分析:這就說明問題了,在函式a(),b()中,區域性指標變數*s1,*s2都指向」hello「字串,但是在退出之前有改變指標指向其他字串,但是兩個字串指標列印出來的位址還是一樣的,說明在使用了字串常量後,該字串常量並沒有在隨著函式的結束而消失,而是依舊存在於記憶體中,因此當其他函式中使用一樣的字串常量時,指向的依舊是跟還是一樣的位址。但是也許有人會問到,因為有在全域性字元指標變數 char *s0 ="hello";指向了該字串常量,會像全域性變數一樣,在真個程式執行都不會釋放,因此其他函式調使用該字串常量時才指向了同一位址。確實確實有這種可能,那麼我們就可以看下面案例三。

案例三:

#include

void a()

void b()

int main()

執行結果:

三個字串指標變數指向的位址還是一樣的,如圖

分析:當我們去掉全域性指標變數後,其結果依舊是*s1,*s2,*s3 三個指標變數指向的位址依舊是沒有變。在執行完a(),b()兩個函式之後,我們再將」「hello」賦值給空指標*s3指標,其指向位址與*s1,*s2都一樣的。因此我們可以得出結論:一旦有字串常量在執行期間建立,就會在記憶體中一直保持到程式結束,當使用相同的字串常量的時候,不會再建立字串常量,而是指向之前的那個。因此字串常量是貫穿整個程式的生命週期的。

以上**在gcc vc上都進行過編譯執行,其結果都一致。

這是本人在csdn的第一篇部落格,發博也是為了與大家溝通交流,向前輩們學習。之前沒有在怎麼用過發過類似的東西,因此在寫的過程中,語言的組織之類,以及在驗證方法的可能會有不科學之處,希望大家指正。我現在還是菜鳥,但是我會一直堅持下去,堅持將自己的看書,學習,專案的經驗心得與大家分享,也希望大家批評指正討論交流。

附:既然說到這裡了,那就再多說一點

案例:當將 char *s0 改為char s0[ ]時

**:#include

char s0="hello";

void a()

void b()

int main()

執行結果:

s0與s1 、s2、 s3指向的位址不同

分析:造成這樣的結果的原因是因為char s0="hello",而*s0指向的是該陣列的首位址,而不是字串的首位址。而*s1、 *s2、 *s3都是指向字串的首位址,因此不同。

關於字串常量在記憶體中的生命週期

字串char s hello 與char s hello 看似都是將hello字串的位址賦值給指標 p。但是前面乙個表示式是字串常量的位址賦值給指標 該指標指向的字串中的字元是不允許被更改的。而後面乙個表示式是將該字串的每乙個字元賦值給陣列,該指標指向的陣列的首位址,而陣列成員是變數,因此可以允許被...

字串常量放在記憶體中的靜態儲存區

一 在c 中,記憶體分成5個區,他們分別是堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區。棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變數的儲存區。裡面的變數通常是區域性變數 函式引數等。堆 就是那些由new分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般乙...

java 掌握字串在記憶體中的分配

解決問題 和equals 的區別?string在記憶體中的分配?stringbuffer在記憶體中的分配?連線兩個字串後的記憶體情況?的底層原理是怎樣的?jdk1.7後常量池轉到堆中,畫圖沒考慮到,但意思 思路是正確的 舉例子 在某方法裡面。故宣告的物件放在棧 總結 1.string是不可變類,不能...