为什么运算符重载会出现自由错误?
Why does free error occurs in operator overloading?
我为 std::string
class 超载了 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;
}
程序因错误而崩溃:
*** 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;
}
直到 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++)
我为 std::string
class 超载了 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;
}
程序因错误而崩溃:
*** 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;
}
直到 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++)