今天白天練習一些程式設計題遇到了乙個問題,是**寫好後總是莫名出現段錯誤,再三檢查語法和演算法,百思不得其解。
之後突然想到,可能是把char *和char搞混了。
原本應該是 char a = 「hello」;
寫成了char * a = 「hello」;
在這之前我一直以為兩者沒有區別,然後仔細的思考了一番,發現了問題的所在。
乙個linux程序分為幾個部分(從乙個程序的位址空間的低位址向高位址增長):
1.text段,就是存放**,可讀可執行不可寫,也稱為正文段,**段。
2.data段,存放已初始化的全域性變數和已初始化的static變數(不管是區域性static變數還是全域性static變數)
3.bss段,存放全域性未初始化變數和未初始化的static變數(也是不區分區域性還是全域性static變數)
以上這3部分是確定的,也就是不同的程式,以上3部分的大小都各不相同,因程式而異,若未初始化的全域性變數定義的多了,那麼bss區就大點,反之則小點。
4.heap,也就是堆
5.stack,棧
6.再往上,也就是乙個程序位址空間的頂部,存放了命令列引數和環境變數。
char * a = 「hello」 初始化後,內容「hello」存放在存放在data段,在這個區域是**編譯後寫在彙編裡的不能改變,而指標變數的位址a存放在棧區,a是可以改變的。所以每次當試圖對data區的內容進行操作是會報出段錯誤。
而char a = 「hello」;初始化時,所有的資料都是在棧區初始化,內容是可變的。
以下為**網路:
第一,如果是全域性的和靜態的
char *p = 「hello」;
這是定義了乙個指標,指向rodata section裡面的「hello」,可以被編譯器放到字串池。在彙編裡面的關鍵字為.ltorg。意思就是在字串池裡的字串是可以共享的,這也是編譯器優化的乙個措施。
char a = 「hello」;
這是定義了乙個陣列,分配在可寫資料塊,不會被放到字串池。
第二,如果是區域性的
char *p = 「hello」;
這是定義了乙個指標,指向rodata section裡面的「hello」,可以被編譯器放到字串池。在彙編裡面的關鍵字為.ltorg。意思就是在字串池裡的字串是可以共享的,這也是編譯器優化的乙個措施。另外,在函式中可以返回它的位址,也就是說,指標是區域性變數,但是它指向的內容是全域性的。
char a = 「hello」;
這是定義了乙個陣列,分配在堆疊上,初始化由編譯器進行。(短的時候直接用指令填充,長的時候就從全域性字串表拷貝),不會被放到字串池(同樣如前,可能會從字串池中拷貝過來)。注意不應該返回它的位址。
關於char 和char 的不同
在c語言中,我們經常用如下兩種方式來表示字串 char string hello world char string hello world 可能有時還會用這種方式 char string 11 hello world 問題來了,他們一樣嗎?不一樣的話有什麼不同?我用如下 來做測試 include ...
關於char 與char 的區別
char a在執行時賦值,值會從靜態區賦值到函式的棧中,對它進行修改不會產生任何問題。char a在編譯時就確定了,a指向靜態區中的值,沒有賦值到函式棧中,因此對指標的內容進行修改會產生錯誤。和許多文章一樣,還是先來了解一下 乙個由 c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stac...
char 和char 的區別
1 char是乙個陣列定義,char 是指標定義 也稱char為靜態陣列,char 為動態陣列 2 指標和陣列的區別 1 指標和陣列的分配 陣列是開闢一塊連續的記憶體空間,陣列本身的識別符號 也就是通常所說的陣列名 代表整個陣列,可以使用sizeof來獲得陣列所佔據記憶體空間的大小 注意,不是陣列元...