2016-01-03 19 views
1

我重載operator*std::string類,但在這種情況下:爲什麼在運算符重載時會發生自由錯誤?

std::string operator*(std::string a, unsigned b) //bad 
{ 
    unsigned old_length = a.length(); 
    a.resize(a.length()*b); 
    for(unsigned i = old_length ;i<a.length()*b; i++) 
     a[i]=a[i%old_length]; 
    return a; 
} 

程序錯誤崩潰:

*** Error in `./program': free(): invalid next size (fast): 0x0000000000cd20b0 *** Aborted

如果我重載它像這樣 - 沒有錯誤:

std::string operator*(std::string a, unsigned b) 
{ 
    unsigned old_length = a.length(); 
    std::string a2 = a; 
    a2.resize(a.length()*b); 
    for(unsigned i = 0 ;i<a.length()*b; i++) 
     a2[i]=a[i%old_length]; 
    return a2; 
} 

那麼問題在哪裏?有沒有辦法創建新的字符串a2?它消耗更多的內存。

#include <iostream> 
#include <string> 

std::string operator*(unsigned b, std::string a) 
{ 
    return operator*(a, b); 
} 

int main(int argc, char **argv) 
{ 
    std::string a = "abcdef "; // if string contains more than 4 symbols - free error for the first case 
    std::string aaaa = 4*a; 

    std::cout << a << "\n" 
       << aaaa << "\n" 
       << std::endl; 
    return 0; 
} 

回答

5

你不能迭代,直到a.length() * b再次(因爲調整後的相當於old_length * b * b)。

條件必須是i < a.length()i < old_length * b

但是爲什麼不使用一些std::string的函數呢?

std::string operator*(std::string a, unsigned b) 
{ 
    a.reserve(a.length() * b); 

    for(unsigned i = 1 ; i <= b; i++) 
     a += a.substr(0, a.length()/b); 

    return a; 
} 

我們還有效地消除old_length變量(在性能方面不那麼有效,看到更好的方法在下面的評論)。

+2

'自動N =則爲a.length(); a.reserve(n * b); while(b--)a.append(a,0,n); return a;'應該更好... – Deduplicator

+0

確實更好:) – LogicStuff

+1

有一些'const'在那裏,是啊 –

3

一旦你這樣做a.resize(a.length()*b);

a.length()發生了變化。

你的循環應該比

for(unsigned i = old_length ;i<a.length(); i++) 
相關問題