2011-12-27 107 views
0

我正在使用Microsoft Visual Studio環境。我遇到了一個奇怪的現象字符串分配

char *src ="123"; 
char *des ="abc"; 
printf("\nThe src string is %c", src[0]); 
printf("\tThe dest string is %c",dest[0]); 

des[0] = src[0]; 

printf("\nThe src string is %c", src[0]); 
printf("\tThe dest string is %c",dest[0]); 

結果是:

1 a 
1 a 

這意味着des[0]沒有被初始化。由於src指向字符串的第一個元素。我想按規則這應該工作。

+1

請用語言標記問題,讓人們知道你在說什麼。 – Oded 2011-12-27 13:46:59

+0

如果你使用C++,爲什麼在世界上你使用'printf'和C風格的字符串? – 2011-12-27 13:50:16

+0

@CodyGray:對不起。我使用C語言作爲平臺。我編輯了標籤。 – vinaygarg 2011-12-27 14:02:55

回答

1

由於SRC和DES用字符串文字進行初始化,其類型實際上應該是const char *,不char *;像這樣:

const char * src ="123"; 
const char * des ="abc"; 

從來沒有分配給他們任何一個的內存,他們只是指向預定義的常量。因此,聲明des[0] = src[0]是未定義的行爲;你試圖在那裏改變一個常數!

任何像樣的編譯器實際上應該警告你從const char *char *隱式轉換...

如果使用C++,可以考慮使用std::string代替char *,並std::cout而不是printf

3

這是未定義的行爲:

des[0] = src[0]; 

試試這個:

char des[] ="abc"; 
+0

謝謝。是的,它確實有效。但是,在這兩種情況下,des都會指向同一個位置。最終'des [0]'相當於'*(des + 0)'。由未定義的行爲,你指的是C規格? – vinaygarg 2011-12-27 13:54:32

+0

@vinaygarg這不是一回事。是的,我正在談論C標準,但我希望C++標準在這方面相似。 – cnicutar 2011-12-27 13:55:51

1

科的ISO/IEC 14882 2.13.4(編程語言 - C++)表示:

  1. 字符串文字是由雙引號所包圍,任選的字符序列(如在2.13.2中定義的)以字母L開頭,如「...」或L「...」。不以L開頭的字符串文字是普通的字符串文字,也被稱爲窄字符串文字。一個普通的字符串文字的類型爲「n常量字符數組」和靜態存儲持續時間(3.7),其中n是下面定義的字符串大小,並用給定字符初始化。 ...

  2. 是否所有字符串文字都是不同的(即,存儲在非重疊對象中)是實現定義的。試圖修改字符串文字的效果是undefined

0

vinaygarg:這意味着des[0]未被初始化。由於src指向字符串的第一個元素。我想按規則這應該工作。

首先,你必須記住* src和* dst被定義爲指針,沒有什麼更多,沒有什麼更少的了。

所以你必須問自己究竟是什麼「123」和「abc」以及爲什麼它不能被改變?長話短說,它存儲在應用程序內存中,它是read-only。爲什麼?字符串必須與程序一起存儲以便在運行時可用於您的代碼,理論上講,您應該得到一個編譯器警告,將非const char*分配給const char *。爲什麼它是read-only? exe和dll的內存需要被保護以免被覆蓋,所以它必須是隻讀的,以防止錯誤和病毒修改執行代碼。

那麼如何將這個字符串轉換爲可修改的內存呢?

// Copying into an array. 
const size_t BUFFER_SIZE = 256; 
char buffer[BUFFER_SIZE]; 
strcpy(buffer, "abc"); 
strncpy(buffer, "abc", BUFFER_SIZE-1); 
+0

@pmg我的歉意,在撰寫本文時並未意識到C-only的要求。更新,謝謝指出。 – 2011-12-27 14:09:44

1

在C中,字符串文字如"123"存儲爲的char陣列(const char在C++)。這些數組存儲在內存中,以便它們在程序的整個生命週期中都可用。嘗試修改字符串文字的內容會導致未定義的行爲;有時它會「工作」,有時它不會,這取決於編譯器和平臺,所以最好將字符串文字視爲不可寫。請記住,在大多數情況下,「T」的「N元素數組」類型的表達式將被轉換爲類型爲「指向T的指針」的表達式,其值是數組中第一個元素的位置。

因此,當你寫

char *src = "123"; 
char *des = "abc"; 

表達式"123"和​​從「的char 3元素數組」到「指針char」轉換,並且src將指向'1'"123"des將指向​​中的'a'

再次試圖修改的未定義行爲一個字符串結果的內容,所以,當你寫

des[0] = src[0]; 

編譯器是免費治療的發言就是了任何方式,從完全無視它完全按照你期望的對任何事情進行干預。這意味着字符串文字或指向它們的指針不能用作調用的目標參數,如strcpy,strcatmemcpy等,也不應將它們用作調用的參數,如strtok