【发布时间】:2018-01-01 13:47:03
【问题描述】:
我构建了一个简单的字符串类。
我尝试制作连接函数,其中一个是+,另一个是+=。
在尝试实现+= 时,我在其下生成了一个Str 对象,该对象等于第一个字符串,其大小为s.size()。但是当我尝试向它附加一个新字符串 t 时,我需要释放旧数组 s 字符串并为其分配新大小。在调用 temp Str 对象的析构函数后,它在释放旧空间时卡在那里,我不明白为什么。如何释放+ 成员函数下的Str?
class Str
{
public:
typedef size_t size_type;
typedef char* iterator;
typedef const char* const_iterator;
iterator begin(){ return p; }
iterator end() { return p + std::strlen(p); }
const_iterator begin() const { return p; }
const_iterator end() const { return p + std::strlen(p); }
size_type size() const { return data_length; }
Str() {};
Str(const Str& s):
p(new char[s.size() +1]),
data_length(s.size())
{
std::copy(s.begin(), s.end(), p);
p[data_length] = '\0';
}
Str(const char* cp) :
p(new char[std::strlen(cp) + 1 ]),
data_length(std::strlen(cp))
{
std::copy(cp, cp+ std::strlen(cp) + 1,p);//copies also the '\0' char to the last place in p
}
Str& operator=(Str& rhs)//assignment operator
{
if (&rhs != this)
{
uncreate();
create(rhs.size());
std::copy(rhs.begin(), rhs.end() + 1, p);
//p[rhs.size()] = '\0';
}
return *this;
}
Str& operator=(const char* cp)//assignment operator
{
if (cp!= p)
{
uncreate();
create(std::strlen(cp));
std::copy(cp, cp+std::strlen(cp), p);
p[data_length] = '\0';
}
return *this;
}
Str& operator+=(const Str&);
~Str()
{
delete[] p;//stucked here while returning from + member function
data_length = 0;
}
const char* c_str() const;
void copy(char* ,size_type);
private:
char* p;
size_type data_length = 0;
const_iterator ci() const { return p; }
void uncreate();
void create(size_type);
};
Str operator+(const Str& s, const Str& t)
{
Str r = s;
r += t;
return r;
}
inline Str& Str::operator+=(const Str &s)
{
//trying to allocate new space for this object
std::copy(s.begin(),s.end(),p+this->size());
p[data_length] = '\0';
return *this;
}
void Str::create(Str::size_type n)
{
p = new char[n + 1];
data_length = n;
}
void Str::uncreate()
{
delete[] p;//to check that p is allocated right
data_length = 0;
}
以main 为例:
int main()
{
Str s1 = "hello";
Str s2 = "worly";
Str s3 = s1 + s2;
return 0;
}
【问题讨论】:
-
你只是don't!使用
std::stringinstread。 -
我尝试释放
r对象?我可以这样做吗? -
像你一样在析构函数中这样做有什么问题?
-
如果这是用于生产工作,请使用 std::string。如果这是一个教育练习,您应该在代码中准确地一个调用 strlen - 在来自
const char*的构造函数中,以初始化datalen。其他所有呼叫都应使用datalen。 (这样,您的字符串 - 如 std::string - 可以包含嵌入的 nul 字符。) -
@axcelenator :您不需要释放器。运算符 + 中
r的析构函数将执行释放。当然,在operator +=,你需要1.分配足够的内存。 2. 从旧内存中复制初始部分。 3. 从 rhs 复制附加的字符串。 4. 释放旧内存。 5.将指针存储在this->p中(第3步需要在第4步之前,以防有人这样做s+=s)
标签: c++ memory-management concatenation