I want to deep copy an array of int. I get an Assertion Error: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) when it goes through the destructor. Which I've been told is because It's trying to delete something that is not there. Please let me know if I am on the right track and just need to change something small, or if I am completely lost and don't know it. I can add more code if needed.
Thanks for the answers.
.h
private:
int* _myArray;
int _size;
int _capacity;
.cpp
MyVector::MyVector()
{
_myArray = new int[2];
_size = 0;
_capacity = 2;
}
MyVector::MyVector(int aSize)
{
_myArray = new int[aSize];
_size = 0;
_capacity = aSize;
}
MyVector::~MyVector()
{
if(_myArray != NULL)
{
delete[] _myArray;
_myArray = NULL;
}
}
MyVector::MyVector(const MyVector& mVector)
{
_capacity = mVector._capacity;
_size = mVector._size;
// if(mVector._myArray)
// {
// _myArray = new int[_capacity];
// copy(mVector._myArray, mVector._myArray+_capacity, _myArray);
// }
}
MyVector& MyVector::operator=(MyVector& setterVect)
{
delete [] _myArray;
if(setterVect._myArray)
{
_myArray = new int[_capacity];
copy(setterVect._myArray, setterVect._myArray+_capacity, _myArray);
}
return *this;
}
You need to make sure you are following the "Rule of Three".
Apart from copy constructor & destructor You should also provide a copy assignment operator which should do a deep copy of dynamically allocated pointer member.
On a side note, the best solution is to simply drop the dynamically allocated member and use a std::vector it saves you all the hassles of manual memory management.
Related
So I am trying to resize an array by making a function call ResizeArray(). However, I don't know what is the correct way to use "delete" in this case. (I make a new int * and copy the value from the original to it and then I make the original pointer points to the new one, now I don't know what to "delete"
class Base
{
private:
int sizeInClass;
int *arrayy=nullptr;
public:
Base(int s)
{
sizeInClass=s;
arrayy = new int[s]{};
setValue();
};
void setValue()
{
for(int x=0;x<sizeInClass;x++)
{
arrayy[x]=x;
}
}
void print()
{
int countter=0;
for(int x=0;x<sizeInClass;x++)
{
countter++;
cout<<arrayy[x]<<endl;
}
cout<<"The size of the array is : "<<countter<<endl;
}
void ResizeArray(int newSize)
{
int *newArray = nullptr;
newArray = new int[newSize];
for(int x=0;x<sizeInClass;x++)
{
newArray[x]=arrayy[x];
}
delete [] arrayy; /////////////////////////////////// should i use deleate here ?
arrayy = newArray;
delete [] newArray; /////////////////////////////////// or should I use deleate here ?
sizeInClass = newSize;
}
~Base()
{
delete [] arrayy; /////////////////////////////////// or just use delete here
arrayy=nullptr;
}
};
int main()
{
Base b(5);
b.print();
b.ResizeArray(8);
b.setValue();
b.print();
return 0;
}
The first and the 3rd of your suggested delete are correct.
Regarding handling resources,
for sure you need de-allocation in destructor, to free resources when your container class
is destroyed. When you want to resize contained array, you are handling it in ResizeArray function, so below is basic proposal for it, with clarification comments:
void ResizeArray(int newSize)
{
int *newArray = new int[newSize];
if (nullptr != newArray) { // we take action only if allocation was successful
for(int x=0;x<sizeInClass;x++)
{
newArray[x]=arrayy[x];
}
delete [] arrayy; // good, here you delete/free resources allocate previously for an old array
arrayy = newArray; // good, you redirect member ptr to newly allocated memory
/* delete [] newArray; ups, we have member ptr point to this location
and we cannot delete it, after this, accessing it would be UB,
beside in dtor we would have double, second deletion */
sizeInClass = newSize;
}
}
Your destructor is fine.
There could be further improvements in your code, but this is related to your question.
I am playing around with my containers.
In my template class for an container i make a pointer of T* (T* mData;) as a member variable of the container class. This is a pointer to an array type.
In the destructor i call the delete keyword delete mData; or delete[] mData; but all i hear is a ding in the test application and no more output is write to the console.
Can someone please explain what is going on is deleting a member of T* mData; somehow different to deleting everything else? if so can someone please explain I've looked everywhere and can't find an answer.
UPDATE
I read the comments and since people were willing to help in return i have decided to post the this update and answer the question itself. Ps don't laugh it was a silly mistake.
OLD CODE (looked something like this)
template<typename T>
class TestVector {
// members
T* mData;
size_t mSize;
// methods
void AddData(T data){
T* buffer;
memcpy_s(buffer, sizeof(mData), mData, sizeof(mData));
if(!buffer){
// log error
return;
}
mSize++;
SafeDelete(mData); // deleting this here was the problem (check destructor)
mData = new T[mSize];
mData = buffer;
mData[mSize - 1] = data;
}
// constructors
TestVector(void){
mData = new T[0];
ZeroMemory(mData, sizeof(mData);
mSize = 0;
}
~TestVector(void){
SafeDelete(mData); // when deleting the mData member again here the problem would occur, the destructor was called the beep noise would sound and the console window would freeze
}
// operators
};
I will answer what i did to change this as a Answer to the question . . .
I will admit i do not understand why deleting the same pointer of the class more than once gave an error, maybe the memory address of the new pointer wasn't know to the class so the destructor couldn't find it but to solve the issue i went with old school C.
template<typename T>
class TestVector {
private:
T * mData;
size_t mSize = 0;
public:
TestVector(void) {
mSize = 2;
mData = (T*)malloc(mSize * sizeof(T));
for (int i = 0; i < mSize; i++) {
mData[i] = i;
}
cout << "Values in t1 are: " << mData[0] << ", " << mData[1] << endl;
}
~TestVector(void) {
free(mData); // only place the pointer is ever deleted
}
public:
void AddData(T data) {
mSize++;
T* newData = (T*)realloc(mData, mSize * sizeof(T));
mData = newData;
mData[mSize - 1] = data;
for (int i = 0; i < mSize; i++) {
cout << "Value: " << i << " is equal to: " << mData[i] << endl;
}
}
};
I just used malloc() to allocate, realloc() to reallocate a bigger array to the pointer and free() to release the pointer.
I could of just omitted the SafeDelete(mData); in the first version and just called new over the top i think but i actually prefer using old school C for this type of thing, it makes more sense :)
Whats going on? Here is the functions it references. I am trying to get this to work as a copy constructor
template <class T>
const queue<Base>& queue<T>::operator=(const queue<Base> &q){
// Doesn't need to copy if they are the same object
if (this != &q){
delete [] data;
length = q.length;
capacity = q.capacity;
front = q.front;
data = new T[capacity];
for (int i = 0; i < capacity; i++){
data[i] = q.data[i];
}
}
return this;
}
This is your error
return this;
this is a pointer. Your operator = is declared as returning a reference. A pointer cannot be converted to a reference. This is what the error message is telling you.
I have class cAuthorisation that manages array of strAuthorisation
function resize prepares aray for next record.
During resize , on line delete [] data; I have crash.
struct strAuthorisation
{
double Amount;
}Authorisation;
class cAuthorisation {
public:
int size;
strAuthorisation *data;
cAuthorisation ()
{
size=0;
}
~cAuthorisation()
{
};
void Add(strAuthorisation )
{
resize();
data[size]=*value;
}
void resize()
{
strAuthorisation *a = new strAuthorisation[5];
size_t newSize = size + 1 ;
strAuthorisation *newArr = new strAuthorisation[newSize];
memcpy( newArr, data, size * sizeof(strAuthorisation) );
size = newSize;
delete [] data;
data = newArr;
}
} Authorisations;
Why it is not possible delete class array?
It crashes because data is an unitialised pointer. delete[] on a null pointer is safe (no-op) so initialise data in the constructor:
cAuthorisation() : size(0), data(0) {}
Note that the class as it stands is violating the rule of three.
Unsure if this is a learning exercise, if it is not use std::vector<strAuthorisation>. The std::vector will dynamically grow as required and automatically destructed when it goes out of scope.
You have not initialized the data pointer. So you are making something like this:
Foo *data;
delete [] data;
"data" is a pointer who's value was never initialized.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have a class defined like:
Class A
{
public:
int num;
A *parent;
vector<A *> children;
...
// constructor without parameters
A(void)
{
this->num = 3;
this->parent = 0;
for (int i=0;i<num;++i)
children.push_back(new A(this,num-1));
}
// constructor with parameters
A(A *a,int n)
{
this->num = n;
this->children->parent = a;
for (int i=0;i<num;++i)
this->children.push_back(new A(this,this->num-1));
}
};
now, the constructor works fine. there are some problem with destructor.
currently, the destructor is defined as:
A::~A(void)
{
if (this->parent!=0) this->parent = 0;
for (int i=0;i<(int)children.size();++i)
this->children[i]->~A();
vector <A *> ().swap(this->children);
}
but every time when I debug it, it will break at:
void deallocate(pointer _Ptr, size_type)
{ // deallocate object at _Ptr, ignore size
::operator delete(_Ptr);
}
it looks like I cannot delete the pointer in the vector of this->children, is there any way that I can de-construct the class successfully?
Your destructor should be:
A::~A(void)
{
for (size_t i=0; i < children.size(); ++i)
delete children[i];
}
You should probably also look into copy constructors. Otherwise, code like this will fail:
{
A foo;
B bar = foo;
}
Becuase you will delete the same pointers twice.
One of these two posts may help you with understanding that: 1 and 2
in the destructor of A, you shouldn't call the destructors of child items explicitly, instead, just delete the elements of the vector. this should be sufficient for your purpose:
A::~A(void)
{
for (size_t i=0; i<children.size(); ++i)delete children[i];
}
Your constructor with parameters has a typo bug in it - this->children->parent will not compiler as children is not a pointer nor does vector have a parent member. I suspect you meant to use this->parent instead.
Your destructor is directly calling the destructor of each child object, which will destroy the child but NOT free its memory. You allocate the child objects with the new operator, so you need to use the delete operator to call the destructor and free the memory correctly.
On a side note, your num member is redundant. You can use children.size() wherever num is needed.
Try this instead:
class A
{
private:
static const int default_num = 3;
public:
A *parent;
vector<A *> children;
...
// default constructor
A()
{
parent = 0;
for (int i = 0; i < default_num; ++i)
children.push_back(new A(this, default_num-1));
}
// constructor with parameters
A(A *a, int n)
{
parent = a;
for (int i = 0; i < n; ++i)
children.push_back(new A(this, n-1));
}
~A()
{
parent = 0;
for (vector<A *>::size_type i = 0; i < children.size(); ++i)
delete children[i];
/*
alternatively:
for (vector<A *>::iterator i = children.begin(); i != children.end(); ++i)
delete *i;
*/
children.clear(); // optional, will be handled when vector is implicitally destructed
}
};