C语言为内存分配空间(代码段、数据段、bss段、存储类、变量的生命周期)
1.linux下C程序為內存分配空間
(1)代碼段
對應著程序中的代碼(函數),代碼段在linux中又叫文本段(.text)
?(2)數據段、bss段
數據段存:顯式初始化為非0的全局變量,顯式初始化為非0的static局部變量
bss段存:顯式初始化為0或者未顯式初始化的全局變量,顯式初始化為0或未顯式初始化的static局部變量。
?(3)堆
C語言中什么樣變量存在堆內存中?C語言不會自動向堆中存放東西,堆的操作是程序員自己手工操作的。程序員根據需求自己判斷要不要使用堆內存,用的時候自己申請,自己使用,完了自己釋放。
(4)文件映射區
文件映射區就是進程打開了文件后,將這個文件的內容從硬盤讀到進程的文件映射區,以后就直接在內存中操作這個文件,讀寫完了后在保存時再將內存中的文件寫到硬盤中去
(4)棧
棧內存區,局部變量分配在棧上;函數調用傳參過程也會用到棧,遞歸函數運行也在棧上
(5)內核映射區
內核映射區就是將操作系統內核程序映射到這個區域了。
對于linux中的每一個進程來說,它都以為整個系統中只有它自己和內核而已。它認為內存地址0xC0000000以下都是它自己的活動空間,0xC0000000以上是OS內核的活動空間。
每一個進程都活在自己獨立的進程空間中,0-3G的空間每一個進程是不同的(因為用了虛擬地址技術),但是內核是唯一的。
?
2.代碼段、數據段、bss段
(1)編譯器在編譯程序的時候,將程序中的所有的元素分成了一些組成部分,各部分構成一個段,所以說段是可執行程序的組成部分。
(2)代碼段:代碼段就是程序中的可執行部分,直觀理解代碼段就是函數堆疊組成的。
(3)數據段(.data段也被稱為數據區、靜態數據區、靜態區):數據段就是程序中的數據,直觀理解就是C語言程序中的全局變量。(注意:全局變量才算是程序的數據,局部變量不算程序的數據,只能算是函數的數據)
(4)bss段(又叫ZI(zero initial)段):bss段的特點就是被初始化為0,bss段本質上也是屬于數據段,bss段就是被初始化為0的數據段。
注意區分:數據段(.data)和bss段的區別和聯系:
- 二者本來沒有本質區別,都是用來存放C程序中的全局變量的。
- 區別在于把顯示初始化為非零的全局變量存在.data段中,而把顯式初始化為0或者并未顯式初始化(C語言規定未顯式初始化的全局變量值默認為0)的全局變量存在bss段。
有些特殊數據會被放到代碼段
- C語言中使用char *p = “linux”;定義字符串時,字符串"linux"實際被分配在代碼段,也就是說這個"linux"字符串實際上是一個常量字符串而不是變量字符串。
const的實現方法至少有2種:
第一種就是編譯將const修飾的變量放在代碼段去以實現不能修改(普遍見于各種單片機的編譯器);
第二種就是由編譯器來檢查以確保const型的常量不會被修改,實際上const型的常量還是和普通變量一樣放在數據段的(gcc中就是這樣實現的)。
3.變量的生命周期
(1)棧變量的生命周期
局部變量(棧變量)存儲在棧上,生命周期是臨時的。臨時的意思就是說:代碼執行過程中按照需要去創建、使用、消亡的。
譬如一個函數內定義的局部變量,在這個函數每一次被調用時都會創建一次,然后使用,最后在函數返回的時候消亡。
(2)堆變量的生命周期
程序使用堆內存的這一段時間,因此堆變量也有了自己的生命周期,就是:從malloc申請時誕生,然后使用,直到free時消亡。
(3)數據段、bss段變量的生命周期
全局變量的生命周期是在程序被執行時誕生,在程序終止時消亡。
全局變量所占用的內存是不能被程序自己釋放的,所以程序如果申請了過多的全局變量會導致這個程序一直占用大量內存。
(4)代碼段、只讀段的生命周期
其實就是程序執行的代碼,其實就是函數,它的生命周期是永久的。
有時候放在代碼段的不只是代碼,還有const類型的常量,還有字符串常量。(const類型的常量、字符串常量有時候放在rodata段,有時候放在代碼段,取決于平臺)
?
總結
以上是生活随笔為你收集整理的C语言为内存分配空间(代码段、数据段、bss段、存储类、变量的生命周期)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux线程的终止
- 下一篇: KITTI数据集下载以及处理