1.結構體中指標變數的深拷貝和淺拷貝
疑問點記錄:
char *p = (char *)malloc(100);
strcpy(p,"renzhenming");
這兩行**定義了乙個字元指標p,他指向堆記憶體中一段空間,這一段空間儲存了乙個字串renzhenming,那麼既然這個指標指向了這塊記憶體,那麼我通過取指標元素符號*應該就可以得到這塊記憶體中的元素了,也就是說按照猜想我列印*p
printf("%s",*p)
應該可以得到值renzhenming這個字串才對,事實上程式卻崩潰了,正確的寫法是這樣
printf("%s",p);
才能得到我們想要的結果:列印出renzhenming這個字串
為什麼?
我想很多初學者可能會有這種疑問,其實深入剖析一下你就會明白了,字元指標char *p他是指向字元的,看下邊的**
char a = 'c';
char *p=&a;
printf("%c",\*p);
這樣是可以列印出c這個字元,為什麼char *p是字元指標卻可以指向乙個字串?c語言是使用字元陣列來表示和儲存字串的,所以可以把字串和字元陣列等價起來,在陣列中,陣列名表示的就是陣列首元素的位址,那麼對字元陣列來說,陣列名表示的就是字元陣列中首個字元的位址,因為字元指標可以儲存字元的位址,那麼就可以使用字元指標來儲存字元陣列的首個字元的位址,也就是字元陣列名
也就是說
char temp[100] ="renzhenming"
和char p = "renzhenming"
表示是同乙個意思,那麼字元指標就是可以指向乙個字元陣列,也就是可以指向乙個字串。陣列名temp和p都是表示的字串renzhenming的第乙個字元 r 的位址。
那麼此時,你就會明白,為什麼p不能把整個字串列印出來了,因為*p表示的是第乙個字元r,你通過%s去接收乙個字元,會導致程式崩潰,如果你這樣列印
printf("%c",*p)
就能列印出r這個字元了。
為什麼通過%s去接收乙個字元會導致程式崩潰?
因為%s格式字串會從給定的記憶體空間開始向後逐個輸出字元,直到遇到\0結束。格式字串為%s時,後面的引數應該為乙個記憶體位址(指標),如果給出的是乙個字元變數,那麼會將字元變數中的值認作位址,例如字元變數ch中儲存的是字元'a',那麼printf會將'a'對應的ascii碼97作為記憶體位址,試圖轉到該位置讀出資料;而該位置的記憶體空間屬於作業系統,為保護段空間不可訪問,因而程式崩潰
那麼為什麼printf("%s",p)可以列印出整個字串?我們知道字串是以\0為結束標誌的,p表示字串第乙個字元的位址,當你通過%s去列印的時候,他會自動向後移動指標,直到找到\0結束符為止,將從p這個為止開始到結束符為止的字元全部列印出來,就是最終的結果了。
#define _crt_secure_no_warnings
#include #include #include typedef struct worker worker;
/* 淺拷貝
*/void lightcopy(worker *temp1, worker *temp2)
void deepcopy(worker *temp1, worker *temp2)
void main()
if (w2.alias != null)
system("pause");
}
簡單來說,深拷貝和淺拷貝針對的是指標,淺拷貝拷貝的是指標的位址值,而深拷貝是拷貝的指標指向的記憶體。
編譯器針對結構體中指向一塊堆記憶體空間的指標進行等號操作,既*p1 = *p2,操作的結果是將p2的位址拷貝到了p1上此時p2和p1指向同一塊記憶體空間。那麼此時,由於執行淺拷貝,當free空間的時候,先判斷if (w1.alias != null)滿足,則將alias指向的空間釋放,再判斷if (w2.alias != null) 仍然滿足,因為w2的alias指標和w1的alias指標並不是同乙個,但是所指向的空間是同乙個,這就導致free空間的時候由於已經被free,再次釋放發生崩潰。深拷貝則可以避免這個問題。
淺拷貝記憶體示意圖.png
深拷貝記憶體示意圖.jpg
13 C語言總結
pragma mark 第一章 c基礎 void func1 void func1 pragma mark 第二章 分支結構 void func2 void func2 printf autumn d autumn 結果 需要注意的是,列舉變數的值是上乙個值 1 autumn 5 pragma ma...
13 C 陣列和元組
如果需要使用同一型別的多個物件,陣列是一種資料結構,它包含同一型別的多個元素 一 一維陣列 1 陣列的宣告方法 int a 因為陣列是引用型別,引用型別有個特點是 宣告變數時不會馬上分配乙個記憶體,只有在用new關鍵字建立例項的時候,才會分配記憶體。2 建立乙個陣列例項 a new int 4 棧裡...
1 3 C 對C的擴充
asm bool true false wchar t namespace using class public protected private friend this inline virtual throw try catch new delete explicit mutable expo...