2013-05-20 80 views
3

請考慮此代碼。瞭解字符串和數組

int main() 
{ 
    char *s, *t; 

    s = malloc(4 * sizeof(char)); 
    strcpy(s, "foo"); 
    t = s; 
    printf("%s %s\n", s, t);   // Output --> foo foo 
    strcpy(s, "bar"); // s = "bar" 
    printf("%s %s\n", s, t);   // Output --> bar bar 
} 

有2個字符串st。首先,我將s設置爲"foo",然後將t指向s。當我打印字符串時,我得到了foo foo

然後,複製"bar"s並再次打印,我得到bar bar

爲什麼t的值在這種情況下發生了變化? (我複製"bar"s爲什麼t改變)。


現在,當我改變strcpy(s, "bar")s = "bar" -

int main() 
{ 
    char *s, *t; 

    s = malloc(4 * sizeof(char)); 
    strcpy(s, "foo"); 
    t = s; 
    printf("%s %s\n", s, t); // Output --> foo foo 
    s = "bar" 
    printf("%s %s\n", s, t); // Output --> bar foo 
} 

此代碼給我foo foobar foo

爲什麼在這種情況下沒有改變?

+3

**版主說明**:玩的很好。保留主題的意見(意思是他們應該要求澄清)。如果你想打開關於這個問題的優點的討論,去[這裏](http://meta.stackoverflow.com)。 –

+1

我已經刪除了你的問題的第二部分,如果你仍然想問它,請另寫一篇文章。你應該每個帖子只問一個問題。 – sashoalm

回答

12

這是undefined behaviour,這意味着任何事情都有可能發生:

char *s, *t; 
strcpy(s, "foo"); 

strcpy()在內存中寫入一個隨機位置,因爲s是一個未初始化的指針。


編輯修正未定義行爲後)

問題1 - 爲什麼在這種情況下,T改變價值? (我複製了「酒吧」爲什麼沒有改變)。

這是一個指針賦值:

t = s; 
兩個 t

和結果s指向相同的內存,這是malloc()並分配給s更早。通過ts可以看到對該內存的任何更改。

問題2 - 爲什麼在第二種情況下不會發生變化?

此字符串文字"bar"的地址分配給s

s = "bar"; 

所以現在ts不指向同一個內存位置。 t指向較早的malloc()並分配給s的內存(因爲指針分配爲t = s;)。

strcpy()=非常不同:

  • strcpy()副本字符由它的第一個參數
  • 分配,=所指定的存儲器地址,改變其中指示器保持
+0

好的,我現在有'malloc' ...仍然是同樣的問題。 – ShuklaSannidhya

+0

爲什麼在第二種情況下沒有改變? – ShuklaSannidhya

+0

所以每當我創建一個字符串文字,它會在內存中創建一個新的位置?像's =「bar」',會先在一個新位置創建一個''bar'',然後將它分配給's'? – ShuklaSannidhya

2
地址
strcpy(s, "foo"); 

份數foo指向由s指向的內存位置 t = s; 現在,ts都指向同一個位置 因此,相同的輸出

現在,您複製bars。由於ts都指向相同的位置。因此,同樣的輸出。


高達此行一切都是相同

s = "bar" 

您創建一個字符串常量bar。並將其地址分配給s。它的一個pointer它可以指向任何內存位置。不一定是原來的。

現在,

sbart仍然在較前位置是在一開始指出,因此輸出

2

一個簡單的方法來了解可能如下: -

 s = malloc(4 * sizeof(char)); // this will be interpreted as follows 
     s = 123 ------------>| | | | | //some garbage values at these location 
          123 124 125 126 // some random address chosen. 

     strcpy(s, "foo") ; // it copies at the address provided by s i.e. 
          |'f'|'o'|'o'|'\0'| 
           123 124 125 126 

     t = s;  this statement means t it pointing to address = 123 

     strcpy(s, "bar"); // this statement copies at given address it means it will override previous value . i.e 
          |'b'|'a'|'r'|'\0'| 
          123 124 125 126 

現在仍然指向地址123這就是爲什麼t,s都打印吧。

 s = "bar" // this will assign a new address to s which is base address of "bar" string . i.e .   
          |'b'|'a'|'r'|'\0'| 
          321 322 323 324  

現在s將包含地址321,而t的值爲123,這就是爲什麼s和t給出不同的值。