2016-01-03 3 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

'автоматического п = 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++) 
Смежные вопросы