指針、內存和字節

指針指向字符串常量,不能給常量賦值。字符常量是不能被重新賦值的。
常量區也是在棧上。在函數體中定義的變量通常在棧上,用malloc、calloc、realloc等分配內存的函數分別得到的就是在堆上。
指針本身存在於棧中,而所指向的對象則不一定。


二.在C++中,內存分成5個區,他們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區
1.棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變量的存儲區。裏面的變量通常是局部變量、函數參數等。
2.堆,就是那些由new分配的內存塊,他們的釋放編譯器不去管,由我們的應用程序去控制,一般一個new就要對應一個delete。如果程序員沒有釋放掉,那麼在程序結束後,操作系統會自動回收。
3.自由存儲區,就是那些由malloc等分配的內存塊,他和堆是十分相似的,不過它是用free來結束自己的生命的。
4.全局/靜態存儲區,全局變量和靜態變量被分配到同一塊內存中,在以前的C語言中,全局變量又分爲初始化的和未初始化的,在C++裏面沒有這個區分了,他們共同佔用同一塊內存區。
5.常量存儲區,這是一塊比較特殊的存儲區,他們裏面存放的是常量,不允許修改(當然,你要通過非正當手段也可以修改)

堆和棧的對比
從以上知識可知,棧是系統提供的功能,特點是快速高效,缺點是有限制,數據不靈活;而棧是函數庫 提供的功能,特點是靈活方便,數據適應面廣泛,但是效率有一定降低。棧是系統數據結構,對於進程/線程是唯一的;堆是函數庫內部數據結構,不一定唯一。不 同堆分配的內存無法互相操作。棧空間分靜態分配和動態分配兩種。靜態分配是編譯器完成的,比如自動變量(auto)的分配。動態分配由alloca函數完 成。棧的動態分配無需釋放(是自動的),也就沒有釋放函數。爲可移植的程序起見,棧的動態分配操作是不被鼓勵的!堆空間的分配總是動態的,雖然程序結束時 所有的數據空間都會被釋放回系統,但是精確的申請內存/ 釋放內存匹配是良好程序的基本要素。

    1.碎片問題:對於堆來講,頻繁的new/delete勢必會造成內存空間的不連續,從而造成大量的碎片,使程序效率降低。對於棧來講,則不會存在這個問題,因爲棧是先進後出的隊列,他們是如此的一一對應,以至於永遠都不可能有一個內存塊從棧中間彈出,在他彈出之前,在他上面的後進的棧內容已經被彈出,詳細的可以>參考數據結構,這裏我們就不再一一討論了。
    2.生長方向:對於堆來講,生長方向是向上的,也就是向着內存地址增加的方向;對於棧來講,它的生長方向是向下的,是向着內存地址減小的方向增長。
    3.分配方式:堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成的,比如局部變量的分配。動態分配由alloca函數進行分配,但是棧的動態分配和堆是不同的,他的動態分配是由編譯器進行釋放,無需我們手工實現。
    4.分配效率:棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。 堆則是C/C++函數庫提供的,它的機制是很複雜的,例如爲了分配一塊內存,庫函數會按照一定的算法(具體的算法可以參考數據結構/操作系統)在堆內存中 搜索可用的足夠大小的空間,如果沒有足夠大小的空間(可能是由於內存碎片太多),就有可能調用系統功能去增加程序數據段的內存空間,這樣就有機會分到足夠 大小的內存,然後進行返回。顯然,堆的效率比棧要低得多。

在C語言中:char a = 'a'; sizeof(char) = 1.sizeof(a) = 1,sizeof('a') = 4;
在C++語言中:char a = 'a'; sizeof(char) = 1.sizeof(a) = 1,sizeof('a') = 1;        //特別注意

32位中char =1,short int =2 ,int =4, long int =4,long long int =8,char* = 4,float = 4,double = 8;
64位中char = 1,short int = 2,int = 4,long int = 8,long long int = 8,char* = 8;float = 4,double = 8;

發佈了24 篇原創文章 · 獲贊 8 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章