#include <queue>
using namespace std;
class Test{
int *myArray;
public:
Test(){
myArray = new int[10];
}
~Test(){
delete[] myArray;
}
};
int main(){
queue<Test> q
Test t;
q.push(t);
}
After I run this, I get a runtime error "double free or corruption". If I get rid of the destructor content (the delete
) it works fine. What's wrong?
This question is related to
c++
runtime-error
delete-operator
Um, shouldn't the destructor be calling delete, rather than delete[]?
The problem is that your class contains a managed RAW pointer but does not implement the rule of three (five in C++11). As a result you are getting (expectedly) a double delete because of copying.
If you are learning you should learn how to implement the rule of three (five). But that is not the correct solution to this problem. You should be using standard container objects rather than try to manage your own internal container. The exact container will depend on what you are trying to do but std::vector is a good default (and you can change afterwords if it is not opimal).
#include <queue>
#include <vector>
class Test{
std::vector<int> myArray;
public:
Test(): myArray(10){
}
};
int main(){
queue<Test> q
Test t;
q.push(t);
}
The reason you should use a standard container is the separation of concerns
. Your class should be concerned with either business logic or resource management (not both). Assuming Test
is some class you are using to maintain some state about your program then it is business logic and it should not be doing resource management. If on the other hand Test
is supposed to manage an array then you probably need to learn more about what is available inside the standard library.
You are getting double free or corruption because first destructor is for object q in this case the memory allocated by new will be free.Next time when detructor will be called for object t at that time the memory is already free (done for q) hence when in destructor delete[] myArray; will execute it will throw double free or corruption. The reason is that both object sharing the same memory so define \copy, assignment, and equal operator as mentioned in above answer.
You need to define a copy constructor, assignment, operator.
class Test {
Test(const Test &that); //Copy constructor
Test& operator= (const Test &rhs); //assignment operator
}
Your copy that is pushed on the queue is pointing to the same memory your original is. When the first is destructed, it deletes the memory. The second destructs and tries to delete the same memory.
You can also try to check null before delete such that
if(myArray) { delete[] myArray; myArray = NULL; }
or you can define all delete operations ina safe manner like this:
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p) { delete (p); (p) = NULL; } }
#endif
#ifndef SAFE_DELETE_ARRAY
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p) = NULL; } }
#endif
and then use
SAFE_DELETE_ARRAY(myArray);
Source: Stackoverflow.com