Reputation: 3095
I'm trying to implement an alternative to usual contiguous dynamic arrays, where I am using a vector of pointers, each is pointing to a constant size array, referring to it as XVector.
It works fine for a certain limit of inputs - say 150 elements -, but beyond that it starts throwing exceptions.
I tried to use "new and delete" instead of "malloc and free", it did increased the limit - say about 1200 elements -, but still exists the same problem.
I'm using C++.
Here's my main program:
XVector<int> xv;
for(int i=0;i<1210;i++){
int temp = rand()%100;
xv.pushBack(temp);
}
for(int i=0;i<xv.size();i++){
cout<<xv.getValue(i)<<" ";
}
cout<<"\n\n"<<xv.capacity();
return 0;
And here's is the XVector (The class of theD header file:
private:
const int b = 10;
vector<T*> arr;
int currentIndex;
int maxSize;
protected:
void expand(){
T* temp = new T[b];
arr.push_back(temp);
maxSize+=(b);
}
void shrink(){
delete[] arr[arr.size()-1];
arr[arr.size()-1] = NULL;
arr.pop_back();
maxSize-=(b);
}
int ceil(float num) {
int inum = (int)num;
if (num == (float)inum) {
return inum;
}
return inum + 1;
}
pair<int,int> position(int index){
pair<int,int> pos;
float result = ((float)index/b);
pos.first = result; //Row #
pos.second = ceil((result - pos.first)*b); //Exact cell in the row
return pos;
}
public:
XVector(){
currentIndex=0;
maxSize=b;
arr.reserve(120);
arr.push_back(new T[b]);
}
void pushBack(T value){
if(currentIndex>=maxSize-1){expand();}
pair<int,int> indeces = position(currentIndex);
arr[indeces.first][indeces.second]=value;
currentIndex++;
}
void popBack(){
currentIndex--;
if(maxSize>=currentIndex+(2*b)){shrink();}
}
T getValue(int index){
pair<int,int> indeces = position(index);
return arr[indeces.first][indeces.second];
}
void setValue(int index,T value){
pair<int,int> indeces = position(index);
arr[indeces.first][indeces.second] = value;
}
int capacity(){
return maxSize;
}
int size(){
return currentIndex;
}
bool empty(){
return currentIndex==0?true:false;
}
PS: I tried to use Valgrind, but failed to identify the exact problem.
Upvotes: 2
Views: 300
Reputation: 481
The main problem of your code that leads your code to crash isn't memory leak. Totally memory leak doesn't leads to crash in short term. in memory leak case your application works until there is enough space on your RAM and then if your RAM being full , crash occurs. you make a mistake in position() method in finding second dimension index.
For example when you call position(index:29) because of implementation of float and float precision result of (result - pos.first)*b is 9.00000095. It means its result has a little difference with real result(9). and then you call ceil(9.00000095) and it return 10 for result. It means you access index 10 for your second dimension whereas you can use index from 0 to 9 and you have index out of range access that leads you to crash after some period of time and your program may have undefined behavior.
the correct sample for position method is :
pair<int, int> position(int index){
pair<int, int> pos;
float result = ((float)index / b);
pos.first = result; //Row #
pos.second = index%b; // changed line
return pos;
}
Finally you should define destructor and delete all memories you allocated by new operator. All of vector element(arrays) need to be deleted.
Upvotes: 0
Reputation: 9347
Your program leaks memory because you never free the pointers in a destructor. You must implement a destructor to solve your memory leak (in addition to a move constructor, copy constructor, assignment copy, and assignment move).
In addition to valgrind, you can use ASAN which has better output and also runs faster.
Upvotes: 4