为什么在运算符重载中会出现自由错误



我已经为std::string类重载了operator*,但在这种情况下:

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;
}

程序崩溃并出现错误:

***"中出错/程序':free():无效的下一个大小(快速):0x0000000000cd20b0***中止

如果我像这样超载-没有错误:

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;
}

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变量(在性能方面不太有效,请参阅下面的评论中的更好方法)。

一旦执行a.resize(a.length()*b);

a.length()已更改。

你的循环应该比

for(unsigned i = old_length ;i<a.length(); i++)

最新更新