在存储器分配方面,我遇到了这三部分代码的问题。我还没有。
请你指出我做错了什么以及我该如何纠正它?
1:
class MyString {
public:
MyString() : str(0) {}
MyString( char *a )
{ str = new char[strlen(a)+1]; strcpy(str,a); }
~MyString() { delete[] str; }
private:
char *str;
friend ostream& operator<<(ostream &os, const MyString &str);
};
ostream& operator<<(ostream &os, const MyString &s)
{
return os << s.str << endl;
}
int main()
{
MyString str("Mitt namn");
MyString *strp = &str;
// alot of code
delete strp;
// alot of code
}
2:定义如上
int main()
{
MyString *str1 = new MyString("Mitt namn");
MyString str2 = *str1;
delete str1;
// alot of code
cout << str2 << endl;
}
3:仍然如上所述
class MyASCII : public MyString {
public:
MyASCII( char *a) : MyString(a), ascii(0)
{
if (a==0) return;
ascii = new int[strlen(a)];
for (int i=0; i<strlen(a); i++)
ascii[i] = int(a[i]);
}
~MyASCII() { delete[] ascii; }
private:
int *ascii;
};
答案 0 :(得分:4)
首先,只使用std::string
。其次,违反三规则。第三,你在delete
中main
一个局部变量,这是错误的。
答案 1 :(得分:2)
std::string
,你为什么不使用它?您的分配语义已被破坏。您需要一个赋值运算符和一个复制构造函数来复制str
所拥有的内存。
在C ++中,拥有一致的复制构造函数,赋值和析构函数至关重要。这是提到的Rule of three DeadMG。您应该阅读相关问题What is The Rule of Three?
复制MyString
时,您的代码会生成浅层副本。因此两个实例共享相同的数据。一旦你销毁了第一个实例,第二个实例就会有一个悬空指针。
您的代码示例1将指向本地变量的指针指定给strp
,然后尝试将其删除。您只能释放使用new MyString(...)
delete
分配的内存。
局部变量的析构函数一旦超出范围就会自动销毁。您不需要(也不能)使用free
手动释放它们。
如果您的类正确实现,代码示例2就可以了。它使用复制构造函数将堆分配的字符串复制到局部变量。但是由于你的复制构造函数实际上没有复制内存,所以它也被破坏了。