#char* 和 char的區別
從一開始寫c 程式,我就一直有乙個疑惑,當自己動手寫的時候這個問題依舊存在,這引起了我的思考,這也許是乙個很基礎的問題但是確實乙個十分重要的問題,不能眼高手低,踏踏實實體會
char *string ="hello" 和 char string = "hello";前面改變他的內容是十分容易崩潰的,但是後者改變他的內容是完全正確的
一.首先要搞清楚記憶體分配
1.記憶體分配有以下幾部份內容組成
1)棧區,由編譯器自動釋放和分配,存放函式的引數值,區域性變數值等。其操作類似與資料結構中的棧
2)堆一般由程式設計師自己申請和釋放,如果程式設計師不釋放,會在程式結束的時候由系統**
3)全域性區,全域性變數和靜態變數儲存是存放在一起的,初始化的全域性變數和靜態變數存放在一快區域,未初始化的全域性變數和靜態變數存放在乙個區域,程式結束後由系統釋放
4)文字常量區--常量字串就是在這裡,最後由系統**
5)**區
也就是說我們的char分配是在棧上,而我們用char* 則分配在字串常量區
二.堆和棧的理論知識
2.1申請方式
棧中申請變數:
由系統自動分配. 比如申請乙個變數
int a;
系統則自動為變數b申請空間,並且在函式結束時候釋放
堆中申請變數:
如p1=(char*)malloc(10);
2.2申請後系統響應
棧:只要棧的剩餘空間大於所申請空間,系統將為程式提供記憶體,否則將報異常提示棧溢位。
堆:首先應該知道作業系統有乙個記錄空閒記憶體位址的鍊錶,當系統收到程式的申請時,會遍歷該鍊錶,尋找第乙個空間大於所申請空間的堆結點,然後將該結點從空閒結點鍊錶中刪除,並將該結點的空間分配給程式,另外,對於大多數系統,會在這塊記憶體空間中的首位址處記錄本次分配的大小,這樣,**中的delete語句才能正確的釋放本記憶體空間。另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閒鍊錶中。
2.3申請大小限制
棧:在windows中,棧是向低位址擴充套件的資料結構,是一塊連續的記憶體區域,這就所為著棧頂的位址和棧的大小是作業系統預先分配好的,總之在windows上預設大小是2m,如果申請的空間大小溢位,則會提示overflow.因此棧申請空間比堆小
堆:是向高位址擴充套件的資料結構,是不連續的記憶體區域.顯然堆空間的獲取比較靈活
2.4申請效率的比較
棧:由系統自動分配,速度較快。但程式設計師是無法控制的。
堆:是由new分配的記憶體,一般速度比較慢,而且容易產生記憶體碎片,不過用起來最方便.另外,在windows下,最好的方式是用virtual alloc分配記憶體,他不是在堆,也不是在棧,而是直接在程序的位址空間中保留一塊記憶體,雖然用起來最不方便。但是速度快,也最靈活。
2.5堆和棧中的儲存內容
棧:在函式呼叫時,第乙個進棧的是主函式中後的下一條指令(函式呼叫語句的下一條可執行語句)的
位址,然後是函式的各個引數,在大多數的c編譯器中,引數是由右往左入棧的,然後是函式中的區域性變數。注意靜態變數是不入棧的。當本次函式呼叫結束後,區域性變數先出棧,然後是引數,最後棧頂指標指向最開始存的位址,也就是主函式中的下一條指令,程式由該點繼續執行。
堆:一般是在堆的頭部用乙個位元組存放堆的大小。堆中的具體內容由程式設計師安排。
2.6訪問效率的比較
char s1="aaaaaaaaaaaaaaa";
char *s2="bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在執行時刻賦值的;
而bbbbbbbbbbb是在編譯時就確定的;
但是,在以後的訪問中,在棧上的陣列比指標所指向的字串(例如堆)快。
因此,總結如下:
1. char p表示p是乙個陣列指標,相當於const pointer,不允許對該指標進行修改。但該指標所指向的陣列內容,是分配在棧上面的,是可以修改的。
2.char * pp表示pp是乙個可變指標,允許對其進行修改,即可以指向其他地方,如pp = p也是可以的。對於*pp ="abc";這樣的情況,由於編譯器優化,一般都會將abc存放在常量區域內,然後pp指標是區域性變數,存放在棧中,因此,在函式返回中,允許返回該位址
例子:#include
#include
#include
#include
#include
#define bufsize 1500
char* getstring()
int main()
但是charp 是乙個區域性變數,他的值是存放在棧上的所以不允許返回
#include
#include
#include
#include
#include
#define bufsize 1500
char* getstring()
int main()
那麼函式返回的是null,因為函式結束棧上的內容會被全部釋放掉
char 和char 的區別
1 char是乙個陣列定義,char 是指標定義 也稱char為靜態陣列,char 為動態陣列 2 指標和陣列的區別 1 指標和陣列的分配 陣列是開闢一塊連續的記憶體空間,陣列本身的識別符號 也就是通常所說的陣列名 代表整個陣列,可以使用sizeof來獲得陣列所佔據記憶體空間的大小 注意,不是陣列元...
char 和char 的區別
char c abc c 0 t char c1 def c1 0 t err 首先c1是乙個指標,它只是指向 def 這個記憶體塊。而 abc 是乙個常量區,不可以對其進行更改。而c定義的是乙個陣列,在分配記憶體時,會自動給它分配四個位元組的位址,並且會進行乙份拷貝工作,此時分配是在棧區進行的,是...
char 和char 的區別
之前在用到char 和char,用到srtncat,讓char對char 進行新增時執行會崩潰,之後做了一些分析和練習,對char 和char有了更深的理解。下面附上一些測試資料。include include include using namespace std int main cout do...