Hey, I am working on a drum machine, and am having problems with vectors.
Each Sequence has a list of samples, and the samples are ordered in a vector. However, when a sample is push_back on the vector, the sample's destructor is called, and results in a double free error.
Here is the Sample creation code:
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;
}
And the 'Dynamo' code that creates each sample in the vector:
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));
}
Here is main():
int main()
{
XDynamo Dynamo;
Dynamo.CreateSample(4,120,2);
Dynamo.CreateSample(8,240,1);
return 0;
}
And this is what happens when the program is run:
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 ***
However, when the delete [] is removed from the destructor, the program runs perfectly.
What is causing this? Any help is greatly appreciated.
You need a proper copy constructor and assignment operator since you have a non-trivial destructor (more accurately because your class wraps a memory allocation). See the 'Rule of the Big 3':
Update:
As Martin York mentioned in the comments, this answer really just addresses the immediate cause of the problem but doesn't really suggest the best way to fix it, which is to use RAII class members that manage the resources automatically. On the face of it (given the example code), the Beat member might be a std::vector<> instead of a pointer to a manually allocated array. A vector<> member would allow the class to not need a special dtor, copy ctor or assignment operator - all those pieces would be automatically provided for the Beat member if it were a vector<>.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With