在代碼調試過程中,還發現了一個比較詭異的事情,char*在使用malloc分配地址之后,如果對其使用字符串賦值,地址竟然會改變!!!逆天啊。
看下面的代碼:
char *pName = (char *)malloc(sizeof(char) * 100); pName = "se";
char *pName = (char *)malloc(sizeof(char) * 100)句為pName分配地址之后,再指向pName = "se",pName的地址會變化。注意指針的賦值,是將指針指向一個新的地址,那么也就是將指針pName指向了"se"的地址。再考慮下面的錯誤代碼,就可以更明白“可以為指針賦值的都是地址”這個道理了:
int *pi; pi = 1; //Error
接下來從頭至尾分析上面的代碼:
char *pName = (char *)malloc(sizeof(char) * 100); char *result = (char *)malloc(sizeof(char) * 50);
此句在執行之后,會為pName和result分配各一個地址,調試結果顯示為:
而在對其進行字符串賦值result = "se";執行 之后,result的地址竟然變化了:
暫時只是奇怪,還不能知道為什么會變化。再對pName進行字符串賦值,(由於個人習慣還是賦值”se”),result和pName竟然指向了同一個地址0x0033544;而如果為pName賦值另外一個字符串,兩者就會指向不同的地址。也就是說,char*被字符串賦值之后,指向的是字符串常量的地址。見下面的截圖對比:
再看地址的數值,malloc所取得的值是0x0015xxxx系列,而字符串常量則位於0x00f4xxxx系列,也就是相差很遠,是不是處在不同的段呢?
進而查閱資料,發現malloc函數是動態分配內存,在堆上開辟內存空間,而字符串常量則是存儲在常量存儲區;兩者位於不同的區域,和上面的分析一致。那么result = "se"句,是對指針result的賦值;指針的賦值是將指針指向一個新的地址。也就是說上句將"se"的地址賦值給了result,”se”代表了地址。
其實C中的字符串存儲於常量存儲區,其本身即代表了字符串的首地址。char*類型的指針,則是可以指向堆區、棧區、常量存儲區任意其一,對應地,常見的char*的指針的指向也是有上面提到的這三種情況:
char c;
char* pc = &c; char* pStr = “se”; char* pChars = (char*) malloc(sizeof(char)*30);
上面代碼中:
-
- pc指向的是棧區中的字符c的地址;
- pStr指向的是常量存儲區中字符串”se”的地址;
- pChars則是指向malloc函數在堆區開辟的空間。
再往深處扒,詳見下篇。
