Reputation: 53
When testing my code, I consistently get errors regarding the use of delete as my class's testbed states that delete is being called on an array allocated with new[]. I have delete in my ~IntVector and two expand functions with the expand functions expanding the capacity while reallocating memory for a dynamically allocated array.
How do I use delete correctly to prevent memory leaks and resolve this error?
main file
#include "IntVector.h"
#include <iostream>
#include <vector>
using namespace std;
IntVector::~IntVector(){
delete[] data;
}
void IntVector::expand(){
cap = cap * 2;
int *data2 = data;
data = new int[cap];
data = data2;
delete data2;
delete[] data2;
}
void IntVector::expand(unsigned amount){
cap = amount;
int *data2 = data;
data = new int[cap];
data = data2;
delete data2;
delete[] data2;
}
header
#ifndef INTVECTOR_H
#define INTVECTOR_H
using namespace std;
class IntVector{
private:
unsigned sz;
unsigned cap;
int *data;
private:
void expand();
void expand(unsigned amount);
};
#endif
Upvotes: 0
Views: 152
Reputation: 15870
In addition to the rule of there violation, you are also attempting to delete variables twice in your expand
functions:
void IntVector::expand()
{
cap = cap * 2;
int *data2 = data;
data = new int[cap];
data = data2;
delete data2; // this should not be here!
delete[] data2; // this will be a problem now!
}
You can only delete data once, and if you created something with new[]
, it needs to be deleted with delete[]
.
Both of your expand functions should look more like:
// copy-swap
void IntVector::expand()
{
IntVector tmp;
tmp.reserve(cap * 2);
tmp.resize(sz);
std::copy(data, data + sz, tmp.data);
std::swap(*this, tmp);
}
or
// raw implementation
void IntVector::expand()
{
unsigned int newCap = cap * 2;
int* newData = new int[newCap];
std::copy(data, data + sz, newData);
delete [] data;
data = newData;
cap = newCap;
}
The copy-swap version would let you reuse the other functions (destructor, copy-assignment operator) and will be more exception safe. The raw implementation should not modify your internal data elements until the new ones are already properly created. This prevents an exception that may be thrown in the new
from leaving your vector in a bad state (e.g. when the cap
is not actually your capacity).
Upvotes: 0
Reputation: 409482
When allocating with new[]
you have to use delete[]
. Your expand
function uses plain delete
. It also contains some other errors (reassigning pointers, double deletion, etc.).
And where's your copy-constructor? Copy-assignment operator? You might want to read about the rule of three.
Upvotes: 3
Reputation: 258698
You're probably running into this issue because you're not obeying the rule of three - you need a copy constructor and an assignment operator in your class that does a deep copy.
If you do something like
IntVector x(IntVector(10));
you'll be left with a dangling pointer in x
, because the original is de-allocated when the temporary IntVector(10)
goes out of scope.
Upvotes: 2