向向量添加时析构函数内部的双重释放
嘿,我在鼓机上工作,矢量有问题。
每个序列都有一个样本列表,这些样本以向量的形式进行排序。然而,当样本在向量上被PUSH_BACK时,该样本的析构函数被调用,并导致双重释放错误。
以下是示例创建代码:
class XSample
{
public:
Uint8 Repeat;
Uint8 PlayCount;
Uint16 Beats;
Uint16 *Beat;
Uint16 BeatsPerMinute;
XSample(Uint16 NewBeats,Uint16 NewBPM,Uint8 NewRepeat);
~XSample();
void GenerateSample();
void PlaySample();
};
XSample::XSample(Uint16 NewBeats,Uint16 NewBPM,Uint8 NewRepeat)
{
Beats = NewBeats;
BeatsPerMinute = NewBPM;
Repeat = NewRepeat-1;
PlayCount = 0;
printf("XSample Construction
");
Beat = new Uint16[Beats];
}
XSample::~XSample()
{
printf("XSample Destruction
");
delete [] Beat;
}
和在向量中创建每个样本的‘Dynamo’代码:
class XDynamo
{
public:
std::vector<XSample> Samples;
void CreateSample(Uint16 NewBeats,Uint16 NewBPM,Uint8 NewRepeat);
};
void XDynamo::CreateSample(Uint16 NewBeats,Uint16 NewBPM,Uint8 NewRepeat)
{
Samples.push_back(XSample(NewBeats,NewBPM,NewRepeat));
}
以下是main():
int main()
{
XDynamo Dynamo;
Dynamo.CreateSample(4,120,2);
Dynamo.CreateSample(8,240,1);
return 0;
}
程序运行时会发生以下情况:
Starting program: /home/shawn/dynamo2/dynamo
[Thread debugging using libthread_db enabled]
XSample Construction
XSample Destruction
XSample Construction
XSample Destruction
*** glibc detected *** /home/shawn/dynamo2/dynamo: double free or corruption (fasttop): 0x0804d008 ***
但是,当从析构函数中删除DELETE[]时,程序可以正常运行。
这是什么原因造成的?我们非常感谢您的帮助。
解决方案
问题是您在对象中动态分配内存,而不是声明复制构造函数/赋值运算符。当您分配内存并负责删除它时,您需要定义编译器生成的所有四个方法。
class XSample
{
public:
// Pointer inside a class.
// This is dangerous and usually wrong.
Uint16 *Beat;
};
XSample::XSample(Uint16 NewBeats,Uint16 NewBPM,Uint8 NewRepeat)
{
// You allocated it here.
// But what happens when you copy this object or assign it to another variable.
Beat = new Uint16[NewBeats];
}
XSample::~XSample()
{
// Delete here. Turns into double delete if you don't have
// copy constructor or assignment operator.
delete [] Beat;
}
执行此操作时,上述内容会发生什么情况:
XSample a(15,2,2);
XSample b(a); // Copy constructor called.
XSample c(15,2,2);
c = a; // Assignment operator called.
解决此问题的两种方法:
- 创建复制构造函数/赋值运算符。
- 使用为您执行内存管理的其他对象。
我会使用解决方案2(因为它更简单)。
这也是一个更好的设计。内存管理应该由他们自己的类来完成,您应该集中精力在您的鼓上。
class XSample
{
public:
std::vector<Uint16> Beat;
};
XSample::XSample(Uint16 NewBeats,Uint16 NewBPM,Uint8 NewRepeat):
Beat(NewBeats)
{
// Notice the vector is constructed above in the initializer list.
}
// Don't need this now.
XSample::~XSample()
{
}
如果您想用硬方法:
Dynamically allocating an array of objects
如果您想在此处查看编译器版本:
C++ implicit copy constructor for a class that contains other objects
相关文章