2012-10-24 38 views
-1

這是我的代碼。我是如何工作但strcpy不是

int main() 
{ 
struct emp 
{ 
    char *n; 
    int age; 
}; 
struct emp e1 = {"Dravid", 23}; 
struct emp e2 = e1; 
strupr(e2.n); 
printf("%s\n", e1.n); 
return 0; 
} 

問題1:根據網站的答案是'DRAVID'是大寫。怎麼樣,e2和e1是一樣的嗎?即如果我這樣做,e2.age ++那麼這個改變是否也會反映在e1中呢?

問題2:如果我將strupr更改爲strcpy,我得到seg故障?爲什麼?即如果我將其更改爲strcpy(e2.n,"hoho");

+0

如果將strupr更改爲strcpy,則應該得到編譯錯誤,因爲strcpy需要2個參數,而不是1. – sashoalm

+2

此外,調用'strupr()'也是UB,它還會嘗試修改字符串就地。 – 2012-10-24 18:21:58

回答

3

你構建你的兩個emp年代後,這是你在內存:

e1.age = 23 
e1.name = 0x12345678 (Which is a pointer in memory to "Dravid") 
e2.age = 23 
e2.name = 0x12345678 (Which is a pointer in memory to "Dravid") 

現在注意到,在你想要做什麼。

  1. 調用strupr(e1.name)是未定義的行爲,因爲您不允許修改字符串文字。
  2. 調用strcpy(e1.name, e2.name)也是未定義的行爲,因爲strcpy要求傳遞給它的兩個指針指向不同的內存塊。此外,它的UB,因爲你不能修改字符串文字。
  3. 調用strcpy(e1.name, "hiho")也是未定義的行爲,因爲您不能修改字符串文字。
+0

它是關於'strcpy(e2.n,「hoho」)',而不是'strcpy(e1.name,e2.name)'。 – glglgl

+0

@glglgl:謝謝,編輯顯然是在我開始迴應之後。 –

+0

@sharth,但網站說,與strupr我會得到DRAVID,怎麼會?如果那也是沒有定義的行爲?我在那裏修改字符串? – Kraken

1

1)分配結構進行成員複製。由於n是一個指針,指針地址被複制,所以它指向同一個字符串。

2)strcpy需要兩個參數。請記住e2.n是一個指針。調用strcpy時,您必須爲該指針分配足夠的空間以容納新字符串的內容。您是與strncpy()更好:

int maxlen = 20; 
e2.n = malloc(maxlen); 
strncpy(e2.n, "Any length string here", maxlen - 1) /* only copies 19 bytes + terminating null */ 
+0

編輯。僅傳遞兩個參數。 – Kraken

1

當一個結構複製到另一個複製在結構中所有的值。對於年齡你只需複製價值,所以你可以改變它,他們會有所不同。

對於n,您正在複製該字符串的地址,因此當您更改其中一個字符串時,您還要更改另一個字符串。

而且,正如H2CO3指出的那樣,您不能修改使用strcpy時嘗試執行的字符串文字。

+1

而且因爲你不能改變字符串文字。 – 2012-10-24 18:22:21

-1

在調用strupr之後它們不應該是相同的(但不管怎樣修改字符串字符串都不安全或不適合)。不,e2的更改將不會反映在e1中,因爲該分配將按值複製對象。

至於更改struc調用strcpy,strcpy有兩個參數,所以只是改變它會導致編譯錯誤。如果添加e1.n作爲第二個參數,它將會崩潰,因爲e2.n尚未初始化爲指向任何內存。

+0

「他們不應該在調用結束之後是相同的 - - 他們應該,因爲他們指向相同(改變)的內存位置。 – 2012-10-24 18:25:45

+0

糟糕,完全錯過了。 – user1610015

+1

請刪除你的答案。 – 2012-10-24 18:49:58

1

Q1。 char * n存儲複製的地址,所以如果你改變兩者的值,它們將被反映出來。 Q2302。 strcpy()需要2個參數,你可以顯示你的代碼是什麼。

+0

這是一個評論/討論而不是答案。 –

0

C與Java不同,它爲不同的變量使用不同的內存區域。因此,當你將一個結構分配給另一個結構時,它實際上是一個區域到另一個區域的淺層副本。通過淺拷貝我的意思是任何指針都沒有遵循,以便對這些指針進行克隆,因此任何指針都會指向同一個地方。它只是一個存儲區域的副本。

要說struct emp e2 = e1;是相同的東西至於說memcpy (&e2, &e1, sizeof(struct emp));

這也就意味着,如果你分配一個結構到另一個結構變量,然後修改其他結構變量的數據,第一個結構變量不改性。

所以在C中,每個變量都是一個不同的內存位置,與Java和其他語言一樣,您正在使用變量引用,而變量名稱只是變量引用的容器(除了內置基本類型的int之外)。

您的代碼中有一點可能存在問題,因爲您使用的是常量字符串。像使用strupr()一樣修改常量字符串是不好的,因爲您不知道如何分配內存或分配內存。所以,通過做一個strupr(),你基本上就很幸運了。

看到這個關於difference between a deep copy and a shallow copy