我已经实现了一个类似于 std::string 的类字符串。 调用析构函数时出现问题:字段长度具有字段中分配的字符的长度。 这是类:
class indexException:public std::exception
{
public:
virtual const char* what()
{
return "Index is either too long, or negative";
}
};
class string
{
public:
static const unsigned int length_max=100;
string(const char* field=NULL)
{
if(field!=NULL)
{
const unsigned int length=strlen(field);
this->field=new char[length+1];
this->length=length;
for(unsigned int i=0;i<=length;i++)
this->field[i]=field[i];
}
else
{
this->field=NULL;
length=0;
}
}
string(string& str)
{
string(str.field);
}
~string()
{
if(length>0)
delete field;
}
char& operator[] (int i) const throw()
{
try
{
if(i<0 || i>=(int)length)
throw indexException();
}
catch(indexException& e)
{
std::cerr << e.what() << std::endl;
}
return field[i];
}
string& operator=(const char* field)
{
const unsigned int length=strlen(field);
if(this->length>0)
delete this->field;
this->field=new char[length];
this->length=length;
for(unsigned int i=0;i<length;i++)
this->field[i]=field[i];
return *this;
}
string& operator= (const string& str)
{
if(this!=&str)
*this=str.field;
return *this;
}
operator char* ()
{
return field;
}
friend std::ostream& operator<< (std::ostream& out, string& str);
friend std::istream& operator>> (std::istream& in, string& str);
public:
unsigned int length;
char* field;
};
std::ostream& operator<<(std::ostream& out, string& str)
{
out << str.field;
return out;
}
std::istream& operator>> (std::istream& in, string& str)
{
char temp[string::length_max];
in >> temp;
str=temp;
return in;
}
如果我使用赋值运算符,这不会导致段错误。 但它间接地导致了它。 我解释如何:
int main(int argc,char** argv)
{
string str="hi";
string str2=str;
return 0;
}
在赋值运算符重载中设置断点,我意识到赋值运算符不会导致段错误。 问题是在退出 main 之后。 如果我删除析构函数,我就不会遇到这个段错误,但我会知道为什么会遇到这个问题。
编辑:我明白问题出在哪里了。 我听从了你的建议,但它仍然会出现段错误。 但是现在它不再在析构函数方法上崩溃,而是在赋值运算符重载上崩溃:
string& operator=(const char* field)
{
unsigned int length=0;
if(field!=NULL)
length=strlen(field);
else
field="";
if(this->length>0)
delete[] this->field;
this->field=new char[length+1];
this->length=length;
strcpy(this->field,field);
return *this;
}
问题是当我删除这个->字段时,调试器停在那里。 段错误示例:
string str("hi");
string str2=str;
这会导致段错误。我认为这是因为 str2 未初始化,并且 length 具有未定义的值。 如果我改为这样做:
string str("hi");
string str2;
str2=str;
没有任何段错误。为什么? 我认为调用:
string str2;
也是在调用构造函数,还是“=”运算符有优先权? 如何解决?
PS:我还改变了其他东西,比如复制构造函数。 完整代码在这里: http://pastebin.com/ubRgaVr8
已解决:我按照接受的回复中的建议更改了复制构造函数:
string(const string& str)
{
length=str.length;
field=new char[str.length+1];
memcpy(field,str.field,length+1);
}
最佳答案
你的复制构造函数没有初始化对象。
string(string& str)
{
string(str.field); // Does nothing
}
string(str.field)
创建一个未命名 string
并立即将其丢弃。
它不会使用不同的构造函数初始化此对象。
由于您的对象现在只包含随机性,因此当您尝试销毁它时会发生不好的事情。
为了确保事情被初始化,创建一个私有(private)成员函数
void initializeFromChars(const char* cString);
完成工作并在您的构造函数和赋值运算符中使用它。
关于c++ - 导致段错误的析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9337423/