为什么我的析构函数仅在其父析构函数调用后才使我的代码崩溃?
Why does my destructor only crash my code after it's called by its parent destructor?
我有一个由 winery
个元素组成的双线程链表,winery
是一个具有自己数据字段的 class。我遇到的问题是 winery
的析构函数:
winery::~winery()
{
delete[] name;
delete[] location;
}
我在 Linux 中收到“双重释放或损坏(输出):0x0000000000402940”错误,我在 Windows Visual Studio 中收到此错误:
所以我在我的 winery
的析构函数上设置了一个断点,发现每次我引用我的 winery 对象时它都会被调用。奇怪的是,唯一一次抛出错误是在调用 winery
的析构函数时,因为我的 list
的析构函数已被调用,即使 winery 已经被调用了两三次。我想知道为什么我的代码第二次没有崩溃 winery
的析构函数,而它的父析构函数没有调用它。
作为一个方面 note/question: 我能够通过删除 winery
的析构函数并将其调用放入其中来解决内存泄漏问题像这样的父析构函数:
list::~list()
{
for (node* next; headByName; headByName = next)
{
next = headByName->nextByName;
delete[] headByName->item.getName();
delete[] headByName->item.getLocation();
delete headByName;
}
}
winery
是名称为 'item'
的类型,getName()
和 getLocation()
是 return 那些 cstrings 的酿酒厂的功能。这行得通,但它违反直觉,而且肯定 似乎 效率低下。是不好的代码吗?我应该使用 `winery 的析构函数并在以某种方式调用它时覆盖它吗?
您的代码似乎在某些指针上多次调用 delete
。
delete[] headByName->item.getName();
delete[] headByName->item.getLocation();
和
delete[] name;
delete[] location;
我建议删除前两行。
此外,正如评论中所建议的那样,由于未在 winery
中实现复制构造函数和复制赋值运算符,您可能会遇到问题。查看 What is The Rule of Three? 以更深入地了解该问题。
您的链表实现有缺陷。您正在存储 winery
而不是指向它的指针。这意味着如果没有适当的深拷贝构造函数,数据不会被复制,只有指针值。这将导致破坏。
修改您的链接列表以存储指针(更好的方法)或提供复制数据的复制构造函数。后者将导致更多的内存分配并且速度变慢,并且不允许您实际更改值,以便存储特定酒厂的每个地方都具有相同的值。
当不使用指针时会发生这样的事情:
{
Winery foo("name"); // constructor copies name to a new buffer
Winery bar = foo; // A new copy is created, shallow copy of data. This means bar.name = foo.name!
...
}
// automatic destruction of objects, both have the same pointers resulting in double free
我有一个由 winery
个元素组成的双线程链表,winery
是一个具有自己数据字段的 class。我遇到的问题是 winery
的析构函数:
winery::~winery()
{
delete[] name;
delete[] location;
}
我在 Linux 中收到“双重释放或损坏(输出):0x0000000000402940”错误,我在 Windows Visual Studio 中收到此错误:
所以我在我的 winery
的析构函数上设置了一个断点,发现每次我引用我的 winery 对象时它都会被调用。奇怪的是,唯一一次抛出错误是在调用 winery
的析构函数时,因为我的 list
的析构函数已被调用,即使 winery 已经被调用了两三次。我想知道为什么我的代码第二次没有崩溃 winery
的析构函数,而它的父析构函数没有调用它。
作为一个方面 note/question: 我能够通过删除 winery
的析构函数并将其调用放入其中来解决内存泄漏问题像这样的父析构函数:
list::~list()
{
for (node* next; headByName; headByName = next)
{
next = headByName->nextByName;
delete[] headByName->item.getName();
delete[] headByName->item.getLocation();
delete headByName;
}
}
winery
是名称为 'item'
的类型,getName()
和 getLocation()
是 return 那些 cstrings 的酿酒厂的功能。这行得通,但它违反直觉,而且肯定 似乎 效率低下。是不好的代码吗?我应该使用 `winery 的析构函数并在以某种方式调用它时覆盖它吗?
您的代码似乎在某些指针上多次调用 delete
。
delete[] headByName->item.getName();
delete[] headByName->item.getLocation();
和
delete[] name;
delete[] location;
我建议删除前两行。
此外,正如评论中所建议的那样,由于未在 winery
中实现复制构造函数和复制赋值运算符,您可能会遇到问题。查看 What is The Rule of Three? 以更深入地了解该问题。
您的链表实现有缺陷。您正在存储 winery
而不是指向它的指针。这意味着如果没有适当的深拷贝构造函数,数据不会被复制,只有指针值。这将导致破坏。
修改您的链接列表以存储指针(更好的方法)或提供复制数据的复制构造函数。后者将导致更多的内存分配并且速度变慢,并且不允许您实际更改值,以便存储特定酒厂的每个地方都具有相同的值。
当不使用指针时会发生这样的事情:
{
Winery foo("name"); // constructor copies name to a new buffer
Winery bar = foo; // A new copy is created, shallow copy of data. This means bar.name = foo.name!
...
}
// automatic destruction of objects, both have the same pointers resulting in double free