2011-09-24 35 views
1

我想創建一個非遞歸方法交換c樣式的字符串。它在Swap方法中引發異常。無法弄清楚問題。C++交換字符串

void Swap(char *a, char* b) 
{ 
    char temp; 
    temp = *a; 
    *a = *b; 
    *b = temp; 
} 
void Reverse_String(char * str, int length) 
{ 
    for(int i=0 ; i <= length/2; i++) //do till the middle 
    { 
     Swap(str+i, str+length - i); 

    } 

} 

編輯:我知道有更奇葩的方法來做到這一點。但是由於我在學習,想知道代碼的問題。

+0

什麼是「例外」?你的意思是它崩潰了嗎?你使用了一個調試器嗎?你用什麼輸入導致它崩潰? – SoapBox

+0

你能提供一個完整的例子(我建議使用ideone.com)編譯正確,運行失敗嗎? –

+0

它崩潰。交換中的EXC_BAD_ACCESS – csharper

回答

7

它在Swap方法中拋出異常。無法弄清楚問題。

不,它不。創建臨時字符並分配字符不可能引發異常。但是,如果您的指針不指向您擁有的內存塊,您可能會遇到訪問衝突。

Reverse_String()函數看起來不錯,假設str指向至少length字節的可寫內存。你的問題沒有足夠的背景來推斷過去。我懷疑你傳遞了無效的參數。您需要向我們展示如何撥打Reverse_String()來確定該通話是否有效。

如果你正在寫這樣的事情:

char * str = "Foo"; 
Reverse_String(str, 3); 
printf("Reversed: '%s'.\n", str); 

然後,你一定會得到一個訪問衝突,因爲str點只讀存儲器。試試下面的語法來代替:

char str[] = "Foo"; 
Reverse_String(str, 3); 
printf("Reversed: '%s'.\n", str); 

這實際上將使"Foo"字符串拷貝到本地緩存可以覆蓋。

+0

哦!我在做前者。 'char str [] =「Foo」;'和'char * str =「Foo」'之間究竟有什麼區別? – csharper

+0

我在哪裏可以閱讀更多。 char * char []字符串和std :: string之間的區別? – csharper

+1

您可以在以下相關問題中閱讀更多內容:[爲什麼簡單的C代碼接收到分段錯誤?](http://stackoverflow.com/questions/164194/why-does-simple-c-code-receive-segmentation-fault) [是否可以修改C中的字符串?](http://stackoverflow.com/questions/1011455/is-it-possible-to-modify-a-string-of-char-in-c) –

2

本答案是由@ user963018發表在@AndréCaron的評論answer(評論太長了)。

char *str = "Foo"; 

以上聲明的指針的char陣列的第一個元素。數組長度爲4個字符,3個用於F,o & o和1用於終止NULL字符。數組本身存儲在標記爲只讀的內存中;這就是爲什麼你得到訪問衝突。實際上,在C++中,您的聲明已被棄用(允許向後兼容C),您的編譯器應該這樣警告您。如果不是,請嘗試調高警告等級。您應該使用以下聲明:

const char *str = "Foo"; 

現在,聲明表示str不應該被用於修改無論它指向的,如果你試圖這樣做,編譯器會抱怨。

char str[] = "Foo"; 

此聲明指出str是4個字符(包括空字符)一個陣列。這裏的區別是str的類型是char[N](其中N == 4),而不是char *。然而,str可以衰減如果上下文需要指針類型,所以你可以將它傳遞給Swap函數,它需要char *。此外,包含Foo的內存不再標記爲只讀,因此您可以對其進行修改。

std::string str("Foo"); 

這聲明包含字符串「foo」 std::string類型的對象。包含字符串的內存由字符串對象根據需要動態分配(某些實現可能包含小型字符串優化的小型私有緩衝區,但現在忘記了)。如果字符串的大小可能有所不同,或者在編譯時您不知道其大小,則最好使用std::string