在 C++ 中测试 deep/shallow 副本时析构函数无法解释的行为
destructor's unexplained behavior while testing deep/shallow copy in C++
class String
{
private:
char* ptr;
public:
String(const String& s1)
{
int len = strlen(s1.ptr);
ptr = new char[len+1];
strcpy(ptr,s1.ptr);
}
String(char* c)
{
int len = strlen(c);
ptr = new char[len+1];
strcpy(ptr,c);
}
~String()
{
cout<<"DELETING\n";
delete[] ptr;
}
void display()
{cout<<ptr;}
};
int main()
{
String s("Waqar"); String* s2 =&s;
String s1(s);
delete s2;
s1.display();
直到倒数第二行delete s2
都没有问题。在调试时,它会抛出一个错误,导致未知信号的影响,并且永远不会执行 s1.display()
。
作为菜鸟,我正在用 C++ 测试深拷贝和浅拷贝概念,因此写了这个垃圾。
我哪里错了?
s2
指向 s
。它是一个指针,根本不是一个副本(浅表或其他)。 new
从未为其分配任何内存。因此,当您尝试删除 s2
时,您是在要求程序释放堆栈上不受 new/delete 管理的内存。在这种情况下不要 delete s2
。这是一个错误。您的析构函数在这里没有错。
这是一个示例程序,详细说明了析构函数的执行方式和时间
调用了不同的点,只有 delete
分配给 new
的内存。
// declare `copy`, but do not initialise it just yet. We want to
// initialise it from `s` (which is not yet declared)
String* copy;
{
// declare and initialise `s`, and copy "Wagner" into s.ptr
String s("Wagner");
// create a new String on the heap, initialised from `s`
// this is a deep copy because of how you wrote String(String&)
copy = new String(s);
s.display();
// `s` falls out of scope at the end of this block
// this means that s.~String() is invoked
}
// `copy` is unaffected as it was declared in the outer scope,
// and because it is a deep copy. Had it been a shallow copy
// then it would be broken as its `char* ptr` would not be valid
// any more.
copy->display();
// copy->~String() is invoked when copy is deleted
delete copy;
class String
{
private:
char* ptr;
public:
String(const String& s1)
{
int len = strlen(s1.ptr);
ptr = new char[len+1];
strcpy(ptr,s1.ptr);
}
String(char* c)
{
int len = strlen(c);
ptr = new char[len+1];
strcpy(ptr,c);
}
~String()
{
cout<<"DELETING\n";
delete[] ptr;
}
void display()
{cout<<ptr;}
};
int main()
{
String s("Waqar"); String* s2 =&s;
String s1(s);
delete s2;
s1.display();
直到倒数第二行delete s2
都没有问题。在调试时,它会抛出一个错误,导致未知信号的影响,并且永远不会执行 s1.display()
。
作为菜鸟,我正在用 C++ 测试深拷贝和浅拷贝概念,因此写了这个垃圾。
我哪里错了?
s2
指向 s
。它是一个指针,根本不是一个副本(浅表或其他)。 new
从未为其分配任何内存。因此,当您尝试删除 s2
时,您是在要求程序释放堆栈上不受 new/delete 管理的内存。在这种情况下不要 delete s2
。这是一个错误。您的析构函数在这里没有错。
这是一个示例程序,详细说明了析构函数的执行方式和时间
调用了不同的点,只有 delete
分配给 new
的内存。
// declare `copy`, but do not initialise it just yet. We want to
// initialise it from `s` (which is not yet declared)
String* copy;
{
// declare and initialise `s`, and copy "Wagner" into s.ptr
String s("Wagner");
// create a new String on the heap, initialised from `s`
// this is a deep copy because of how you wrote String(String&)
copy = new String(s);
s.display();
// `s` falls out of scope at the end of this block
// this means that s.~String() is invoked
}
// `copy` is unaffected as it was declared in the outer scope,
// and because it is a deep copy. Had it been a shallow copy
// then it would be broken as its `char* ptr` would not be valid
// any more.
copy->display();
// copy->~String() is invoked when copy is deleted
delete copy;