c++ 中的自串联
Self-Concatenation in c++
我正在处理一个字符串 class,其中 int
代表长度,char*
代表数据。我已经覆盖了 +=
运算符,它工作得很好,除非你尝试自连接,例如:
String s1 = "Hello";
s1 += s1;
cout << s1;
这个returns:À$p
或者其他奇怪的字符。这是我的相关代码:
#include <iostream>
#include <cstring>
#include "assert.h"
using namespace std;
class String{
public:
int len;
char *str;
String()
:len(0), str(nullptr){}
String(char const* S)
:len(strlen(S)), str(new char[len +1]){
assert(S != 0);
strcpy(str, S);
}
~String(){
delete[]str;
}
char* data() const{
return this->str;
}
String operator +=(String const &S){
int n = this->len + S.len;
char * p = new char[n+1];
strcpy(p + len, S.str);
len = n;
str = p;
return *this;
}
};
std::ostream& operator <<(ostream& os, String const& str){
return os << str.data();
}
int main()
{
String g1 = "Hello";
g1 += g1;
cout << g1;
return 0;
}
这段代码有几个问题。首先,回顾一下 Rule of Three/Five/Zero is.
现在,实际operator+=
存在三个问题:
您实际上并没有将字符串的初始部分复制到 p
。你只是在复制后半部分。您需要执行以下操作:
memcpy(p, str, len);
memcpy(p + len, S.str, S.len);
您没有清理旧内容。当你写 str = p;
时,你只是泄露了 str
指向的内存。你需要写:
delete [] str;
在你做那个作业之前。
您返回的是一个会立即销毁的临时文件。缺少复制构造函数(请参阅初始点)意味着您正在破坏 g1
的缓冲区,然后当您尝试 main()
末尾时出现双自由损坏错误 delete[]
再说一遍。这个问题可以通过编写一个有效的复制构造函数来解决,但是 operator+=
不应该返回一个临时的 - 它应该返回一个引用:
String& operator+=(String const& S) { ... }
我正在处理一个字符串 class,其中 int
代表长度,char*
代表数据。我已经覆盖了 +=
运算符,它工作得很好,除非你尝试自连接,例如:
String s1 = "Hello";
s1 += s1;
cout << s1;
这个returns:À$p
或者其他奇怪的字符。这是我的相关代码:
#include <iostream>
#include <cstring>
#include "assert.h"
using namespace std;
class String{
public:
int len;
char *str;
String()
:len(0), str(nullptr){}
String(char const* S)
:len(strlen(S)), str(new char[len +1]){
assert(S != 0);
strcpy(str, S);
}
~String(){
delete[]str;
}
char* data() const{
return this->str;
}
String operator +=(String const &S){
int n = this->len + S.len;
char * p = new char[n+1];
strcpy(p + len, S.str);
len = n;
str = p;
return *this;
}
};
std::ostream& operator <<(ostream& os, String const& str){
return os << str.data();
}
int main()
{
String g1 = "Hello";
g1 += g1;
cout << g1;
return 0;
}
这段代码有几个问题。首先,回顾一下 Rule of Three/Five/Zero is.
现在,实际operator+=
存在三个问题:
您实际上并没有将字符串的初始部分复制到
p
。你只是在复制后半部分。您需要执行以下操作:memcpy(p, str, len); memcpy(p + len, S.str, S.len);
您没有清理旧内容。当你写
str = p;
时,你只是泄露了str
指向的内存。你需要写:delete [] str;
在你做那个作业之前。
您返回的是一个会立即销毁的临时文件。缺少复制构造函数(请参阅初始点)意味着您正在破坏
g1
的缓冲区,然后当您尝试main()
末尾时出现双自由损坏错误delete[]
再说一遍。这个问题可以通过编写一个有效的复制构造函数来解决,但是operator+=
不应该返回一个临时的 - 它应该返回一个引用:String& operator+=(String const& S) { ... }