添加到向量后,在析构函数内部双重释放

Sha*_*ley 2 c++ destructor vector double-free

嘿,我正在打鼓机,我遇到了矢量问题.

每个序列都有一个样本列表,样本按向量排序.但是,当样本是向量上的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\n");
    Beat = new Uint16[Beats];
}

XSample::~XSample()
{
    printf("XSample Destruction\n");
    delete [] Beat;
}
Run Code Online (Sandbox Code Playgroud)

以及在向量中创建每个样本的'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));
}
Run Code Online (Sandbox Code Playgroud)

这是main():

int main()
{
    XDynamo Dynamo;

    Dynamo.CreateSample(4,120,2);
    Dynamo.CreateSample(8,240,1);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是程序运行时发生的情况:

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 ***
Run Code Online (Sandbox Code Playgroud)

但是,当从析构函数中删除delete []时,程序运行完美.

是什么造成的?任何帮助是极大的赞赏.

Mic*_*urr 8

您需要一个正确的复制构造函数和赋值运算符,因为您有一个非平凡的析构函数(更准确地说,因为您的类包装了内存分配).参见"大三规则":


更新:

正如Martin York在评论中提到的,这个答案实际上只是解决问题的直接原因,但并没有真正提出解决问题的最佳方法,即使用自动管理资源的RAII类成员.从表面上看(给定示例代码),Beat成员可能是std::vector<>一个指向手动分配的数组的指针.一个vector<>成员将允许类不需要特殊的析构函数,复制构造函数或赋值运算符-所有这些作品将被自动提供给Beat成员,如果它是一个vector<>.