2015-12-18 57 views
0

我寫了一個函數,將字符串「rdd」的順序顛倒爲「ddr」, 當我運行它時出現子串超出範圍的錯誤。任何幫助表示讚賞!子串超出範圍

#include <iostream> 
#include <string> 
#include <stdio.h> 
#include <ctype.h> 
using namespace std; 

string reverse(const string & s); 

int main() { 
    cout << reverse("rdd") << endl; 
} 

string reverse(const string & s) { 
    string rname(s); 
    for (unsigned i = rname.size()-1; i >= 0; i--) { 
     cout << rname[i]; 
    } 
    return rname; 
} 
+1

你意識到這只是以相反的順序寫出字符串,但實際上並沒有反轉字符串,對吧?它複製提供的字符串,根本不會更改副本,並在以相反順序打印後返回未修改的副本。 – ShadowRanger

+0

由於'i'是無符號的,因此當'i'爲0然後遞減時,它變成一個非常大的正數,因此超出範圍 – steveo225

+0

而且變量'i'具有什麼值,當它的值等於' 0'(仍然滿足'i> = 0'條件),並且它被'i - '減1。 –

回答

1

您的i是無符號的,因此總是滿足條件i> = 0。試想一下:

unsigned int i = 0; 
i--; // i will undeflow, and assume the largest unsigned number possible 
if(i < 0) printf("Works?"); // suprise! It will be false and printf does not fire! 
3

這是問題:

for (unsigned i = rname.size()-1; i >= 0; i--) { 

由於i是無符號,i--將採取從0UINT_MAX。對於unsigned int,測試i >= 0永遠不會失敗。發生這種情況後,您可以訪問循環體中的界限。

取而代之的是循環可能看起來像:

for (unsigned i = rname.size(); i --> 0;) 

(使用--> operator),或一個更好的選擇是使用C++成語:

for (auto it = rname.rbegin(); it != rname.rend(); ++it) 
    cout << *it; 

也看到reverse adapters儘管這可能是矯枉過正對於這種情況。

+0

你的循環與 - >是輝煌的! – PiotrK

+2

之前從未看到過這種情況是否確實鼓勵了令人困惑的' - >'「運算符」?真?迭代器的方法是安全的,不涉及可愛的語法技巧。 – ShadowRanger

+0

@ShadowRanger以及你可以寫'i - > 0'爲正常:) –

0
for (unsigned i = rname.size()-1; i >= 0; i--) { 

的問題是在上面的語句,因爲 - rname.size()將返回字符串的長度。因此,這個循環將從rname.size()-1運行到0(包括),然後我將是UINT_MAX和條件是i> = 0,將始終爲真,但您的字符串大小可能會小於UINT_MAX,因此它會返回一個錯誤的約束錯誤。