2013-04-10 86 views
2

在C++中,爲什麼編譯器不允許修改以下字符指針如下訪問字符指針

#include <iostream> 

int main() 
{ 
char* cp = "overflow"; 
cp[1]='p'; 
return 0; 
} 

輸出:在運行時崩潰。

但字符數組允許,

#include <iostream> 

int main() 
{ 
char cps[] = "overflow"; 
cp[1]='p'; // this compiles fine and output is operflow 
return 0; 
} 

只是想知道什麼是在運行時發生的事情,爲何導致崩潰。謝謝。

+1

'char cps =「overflow」;'是錯的,你的意思是'char cps [] =「overflow」;'? – unwind 2013-04-10 11:35:28

+0

@unwind對不起,它失蹤了。更正.. – 2013-04-10 11:39:03

回答

9

字符串文字是char const[]類型的左值,其中const是重要部分。試圖修改類型爲const的對象是未定義的行爲

每個段落的C++ 11標準2.14.5/8:

普通字符串和UTF-8字符串文字也稱爲窄字符串文字。 窄 字符串文字具有類型,其中Ñ是字符串的尺寸如下面所定義,且具有 靜態存儲持續時間(3.7)「的Ñconst char陣列」。

在第二種情況下(假設你的意思char cps[] = "overflow";,用方括號),要初始化字符串字面的非const副本。修改該副本即可。

還要注意,從一個字符串非-constchar *轉換已被棄用在C++ 03和非法在C++ 11。這一點,在另一方面,是合法的:

char const* cp = "overflow"; 
// ^^^^^ 
+0

在大多數編譯器上,至少應該至少有一個警告,即使是在C++ 11之前? – drquicksilver 2013-04-10 11:39:44

+0

@drquicksilver:在GCC上有提供足夠的警告級別。 – ereOn 2013-04-10 11:40:19

+0

@ Andy,爲什麼它被視爲char const [],它背後的任何有效理由? – 2013-04-10 11:42:17

2

此:char* str="";,是一個字符串文字,並且可以存儲在只讀內存部分,因此可能會崩潰。使用const char* const str="string";(包括指針和數據不變或至少該數據應該是恆定的:const char* str="string";char const* str="string";

如果試圖改變一個字符串的內容文本是未定義的行爲和分割故障導致的碰撞可能發生。

0

當您設置char* cp = "overflow";時,您正在創建一個只讀的內存塊,其中包含"overflow"(後跟NULL結束字節),因此您不能在此處寫入。試圖改變c[x]需要寫在那裏。

至於你的第二塊代碼 - 缺少某些東西,以至於部分問題還不清楚。

0

因爲指向字符的指針不是arraylow-level const。你可以做

char cp[] = {'o', 'v', 'e', 'r', 'f', 'l', 'o', 'w', '\0'}; 

char *pcp = cp; 

*++pcp = 'p'; 

然而,"overflow"是字符常量序列是不可修改的,因此,你只能執行指針算術和反引用指針的值。

char *cp = "overflow"; 

std::cout << *++cp std::endl;