只读字符串的c语言命令,C语言只读空间 - C 语言程序设计
我們現在看向內存中的只讀數據段和代碼段構成的只讀空間的概念。
代碼段
當程序越來越多,代碼段也就越來越大。代碼段里面的代碼是不可以在運行的時候被修改的,在編譯的時候就已經定格了。如果我們試圖去寫它,就一定會出現段錯誤。
測試代碼如下
我們定義了一個unsigned char類型的指針去指向main函數的地址,強制轉換之后告訴編譯器我們需要用這樣方式讀取。在獲取到main函數地址之后,我們對這個字節的內容進行讀取;然后再將它的值試圖修改,然后再輸出。
運行結果如下
我們成功的訪問到了main函數的地址里面的數據,但是在試圖修改它的值的時候,編譯器報出了一個段錯誤。一旦我們操作代碼段,操作系統就會認為程序是非法程序,然后將程序關閉掉。
只讀數據段
下面就是一個關于只讀數據段的一個經典錯誤:
測試代碼如下
p1是一個普通的指針變量,但是它指向的卻是一個常量字符串,這個字符串就保存在只讀數據段中,它首先將這個字符串輸出了。在第二個打印函數中,我們打印的是一個字符串“Hello world”的地址,這樣可以看出它存儲的段。再下面我們試圖通過可變的指針去修改常量段的數據。
運行結果如下:
打印了這個字符串,還獲取到了常量字符串的首地址,可以看到和我們的代碼段相隔很近。我們修改常量段導致了一個段錯誤。
除了只讀空間和內核空間以外,其它的空間就是一個可讀可寫的空間。如果我們定義了一個const int a=10;通過一個指針去修改它,a的值是可以被修改的。因為a是一個局部變量,系統不會將它放在只讀數據段中,會將它放在局部變量中,這就是C的定義方式。
我們可以通過size build命令查看各個段中的大小。紅色方框中為靜態的數據段,程序在運行之前就被打包在那里。在匯編之后生成了一堆原材料,將這些原材料打包成一個可運行程序,將這些數據分別放到這三個段中(代碼段(TEXT),只讀數據段(TEXT),全局的數據空間(data和bss)。
我們在其中一個輸出字符串的前面加了1234,由于他們是字符串,所以它們應該比原來多了4個字節。(為什么我們沒有修改第一個輸出字符串the p1 is,是因為下面還有一個輸出相同的字符串,可能會因為編譯器的優化導致代碼段的優化保存,就不是添加四個字符了。)
運行結果如下
我們可以看到前后之間的區別,text段的數據多了四個字節,是因為我們添加了四個字符的結果。
對于我們嵌入式開發而言,這個程序的代碼段就不能太大。比如路由器,它的成本比較低,flash存儲器非常小,只有一兩兆,如果我們的Text太多,占據了太多的空間,那么就顯得太多余臃腫。所以最終生成的Release版本的程序有些打印信息是要去掉的。我們在實際工程中,debug版本是無所謂的,但是Release版本我們就需要對一些字符串進行裁剪,減小可執行程序代碼的大小,尤其是嵌入式模板開發中,這個非常關鍵。
總結
以上是生活随笔為你收集整理的只读字符串的c语言命令,C语言只读空间 - C 语言程序设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言作业皇帝的许诺,C语言函数大全(s
- 下一篇: 黑白子交换c语言思路,递归 算法思路和优