2009-10-11 55 views
1

在C/C++的一些人使用C風格的字符串,如:c風格的字符串是否安全?

char *str = "This is a c-styled string"; 

我的問題是這是安全的?我看到它的方式是他們創建了一個char指針,它指向一個常量字符數組的第一個字母,但不能用其他的東西,例如另一個變量覆蓋內存中char數組的一部分?從而導致str邏輯無效?

+3

這聞起來像'爲const char *'。 – Zed 2009-10-11 13:28:39

+0

也氣味重複:http://stackoverflow.com/questions/349025/is-a-string-literal-in-c-created-in-static-memory – Zed 2009-10-11 13:31:04

+0

這取決於你的「安全」的定義。使用'std :: string'肯定更安全。 – sbi 2009-10-11 15:45:45

回答

7

現在,字符串常量被放在二進制文件的只讀段中。如果您嘗試在只讀區域寫入地址,則CPU的內存管理單元將導致故障,並且您的應用程序將獲得訪問衝突或分段錯誤或其他取決於操作系統的行爲。

此外,如果您將字符串常量的類型聲明爲非常量,編譯器會發出警告。

+0

存儲在只讀內存部分...現在一切都很有意義... thx〜 – user176121 2009-10-11 13:40:34

+1

非Intel-y有相當大的世界,甚至非MMU環境,在這裏不會是案件。由於C或C++標準沒有定義(與實現定義的*非常*不同),因此C或C++標準中沒有任何內容規定了此行爲。您可能想清楚地說明,對於支持它的體系結構來說,這個答案是很常見的做法,但決不是強制性的。 – paxdiablo 2009-10-12 01:56:53

+0

1請調整參數@paxdiablo。 – 2011-05-26 18:00:51

1

這是不安全的。但在C/C++中也是如此。您可以輕鬆地覆蓋其他對象使用的內存部分。

0

不要真正做到這一點:

int *foo = 0x1234; 
byte[] bytes = (byte[]) foo; 
bytes[0] = 0x56; 

printf("%d\n", *foo); 

也就是說,如果使用不當,任何指針是很危險的。

6

但不能有其他的東西,例如另一個變量覆蓋內存中的字符數組的一部分?

他們一定不要那樣做。其原因是,你的C-字符串字面量是一個常數正確,應該被宣佈爲一個:

char const* str = "This is a c-styled string"; 

你(非const)代碼,只允許出兼容的遺留C代碼。嘗試修改數據導致未定義的行爲。

+3

它應該是const char str [],它是真正的類型。爲什麼會丟失編譯時大小信息? – 2009-10-11 14:46:18

+0

@fnieto:好評。這會被優化爲指向一個字面值,還是會被複制(儘管'const'限定符)?我恨所有我的文字字符串被複制。 – 2009-10-11 14:53:23

+0

@fnieto:雖然語義不同。 Konrad說,如果它被聲明爲一個數組,你會得到一個靜態分配的字符串的本地副本。用char指針,你只需指向原始的靜態分配的字符串。 – jalf 2009-10-11 14:57:56

3

事情就像你做的一樣安全。您可以像堆疊字符串一樣輕鬆地覆蓋堆棧上的整數。事實上,你的問題在某些系統中是安全的,因爲它可能被放置在只讀存儲器部分。

如果人們不知道自己在做什麼,就不應該使用C語言。就像他們不應該沒有經過適當訓練就使用電鋸一樣。 C的全部存在理由是一種系統編程語言。它給你充分的權力去做你想做的事。隨着權力來自責任。

0

取決於你的意思是「安全」。

它們的本質安全性不低於C/C++中其他任何指針的使用。指針一般要求你對記憶非常小心。

1

它們與您的編程實踐一樣安全。只要你知道如何正確地使用它們,它們就是完全安全的。對於那些編程風格讓人想到瓷器店裏的大象的人來說,這樣的字符串可能並不安全。但是關於整個C/C++語言可以說同樣的事情。

您最初的單行申報示例已經遭遇了不安全的樣式問題。在C和C++中,字符串都是不可修改的左值。創建指向這些文字的[長壽命]非常量指針並不是一個好主意。通常,它應該看起來如下

const char *str = "This is a c-styled string"; 

請注意額外的'const'。

(這個特殊的規則不能始終遵循在C,但通常只需要違反它在某些控制良好的本地化慣用的代碼。)

相關問題