我正在练习C ++。
我在两个版本中实现String类。在第一个版本中,文本保存在数组中。在第二个版本中,文本保存在动态分配内存中。第二个版本继承 第一个。
第一个版本正常。 在第二个版本中,在concat函数的第一行,我得到一个错误的分配异常。
这是代码:
#include<iostream>
#include<string>
using namespace std;
class String{
protected:
enum{SIZE=256};
void setLen(const int length)
{
m_len = length;
}
private:
int m_len;
char m_text [SIZE];
public:
String()
{
m_len = 0;
strcpy_s (m_text, 1, "");
}
String(const char* text)
{
m_len = strlen(text);
strcpy_s (m_text, strlen(text) + 1, text);
}
const char* get() const
{
return m_text;
}
virtual void set(char* text)
{
strcpy_s (m_text, strlen(text) + 1, text);
}
int getLen() const
{
return m_len;
}
virtual void concat(const String &s)
{
strcat_s(m_text, strlen(m_text) + strlen(s.get()) + 1, s.m_text);
}
bool equal(const String &s)const
{
return strcmp(s.m_text, m_text);
}
bool operator ==(const String &s)const
{
return strcmp(s.m_text, m_text);
}
virtual void print()const
{
cout<<m_text;
}
};
class PointString :public String {
char* m_text;
public:
PointString()
{
setLen(0);
m_text = new char[1];
strcpy_s(m_text, 1,"");
}
PointString(const char* text)
{
setLen(strlen(text));
m_text = new char[strlen(text)+1];
strcpy_s(m_text, strlen(text)+1 ,text);
}
void set(char* text)
{
delete [] m_text;
setLen(strlen(text));
m_text = new char[strlen(text)+1];
}
void concat(const String &s)
{
char *temp = new char[strlen(m_text) + strlen(s.get())];
strcpy_s(temp, SIZE, m_text);
strcat_s(m_text,strlen(m_text) + strlen(s.get()) + 1, s.get());
delete [] m_text;
m_text = temp;
}
void print()const
{
cout<<m_text<<endl;
}
};
void main()
{
PointString str("1234");
str.print();
str.concat("8901");
str.print();
system("pause");
}
答案 0 :(得分:1)
问题出在concat
来电:
char *temp = new char[strlen(m_text) + strlen(s.get())]; // 1
strcpy_s(temp, SIZE, m_text);
strcat_s(m_text, strlen(m_text) + strlen(s.get()) + 1, s.get()); // 2
delete[] m_text;
m_text = temp;
对于问题// 1
,您没有为字符串分配足够的空间。您忘记了终止NULL条目。
对于问题// 2
,在正确调整大小之前,您将连接到m_text
。
使用标准字符串函数,以下更改不会导致任何问题:
char *temp = new char[strlen(m_text) + strlen(s.get()) + 1];
strcpy(temp, m_text);
strcat(temp, s.get());
delete[] m_text;
m_text = temp;
使用Microsoft安全字符串函数,您应该将新字符串的长度保存在变量中,并在每次调用中使用它。指定SIZE
似乎不正确。这对我有用:
void concat(const String &s)
{
size_t sz = strlen(m_text) + strlen(s.get()) + 1;
char *temp = new char[sz];
strcpy_s(temp, sz, m_text);
strcat_s(temp, sz, s.get());
delete[] m_text;
m_text = temp;
}
您的代码还有其他问题。一个是缺少析构函数,因此每当您创建PointString
时都会出现内存泄漏。另一个问题是,由于缺少用户定义的复制构造函数和赋值运算符,将PointString
复制并分配给另一个PointString
将无法正常工作。
请阅读上述主题,因为无法复制自己的字符串类实际上不值得使用(如果您打算使用它),除了存在内存泄漏之外根本无法使用(没有析构函数)。
如果你将自己从&#34;家庭作业&#34;阶段,std::string
课程完成您现在正在做的所有工作,除了更安全和有效。