Memory leak in using a list of lists - c++

I had some code thrown at me to 'productionize.' I ran a memory leak checker and it calls out the following line within the 'for' loop below as a memory leak.
someStruct->arrayMap = new std::list<BasisIndex>*[someStruct->mapSizeX];
for(int i=0; i<someStruct->mapSizeX; i++){
someStruct->arrayMap[i] = new std::list<BasisIndex>[someStruct->mapSizeY];
}
Here is how the array map is declared:
struct SomeStruct{
int mapSizeX;
int mapSizeY;
std::list<BasisIndex>** arrayMap;
};
Here are a couple usages of it:
someStruct->arrayMap[xVal][yVal].push_back(tempIndex);
for(it = someStruct->arrayMap[xVal][yVal].begin(); it != someStruct->arrayMap[xVal][yVal].end(); it++){
...
}
The memory leak checker dumped for 5 minutes before I killed it. Then I added the following bit of code in a cleanup routine but it still dumps out 150 warnings all pointing to the line of code within the for loop at the top.
for(int x=0; x<someStruct->mapSizeX; x++){
for(int y=0; y<someStruct->mapSizeY; y++){
someStruct->arrayMap[x][y].clear();
someStruct->arrayMap[x][y].~list();
}
}
std::list<BasisIndex> ** temp = someStruct->arrayMap;
delete temp;
How do I completely delete the memory associated with this array map?

Deallocate the objects in the reverse order that you allocated them.
Allocation:
someStruct->arrayMap = new std::list<BasisIndex>*[someStruct->mapSizeX];
for(int i=0; i<someStruct->mapSizeX; i++){
someStruct->arrayMap[i] = new std::list<BasisIndex>[someStruct->mapSizeY];
}
Deallocation:
for (int i=0; i<someStruct->mapSizeX; i++){
delete[] someStruct->arrayMap[i];
}
delete[] someStruct->arrayMap;

someStruct->arrayMap[x][y].~list(); <-- You should not call the destructor manually. (I didn't even know it was valid to do it that way when placement new wasn't used first...) You need to use delete instead.

Related

I have difficult to delete pointers in array

I try to clean the memory to delete pointers. But the last instruction (delete array[i]) generate this error :
pointeurs-tableau(14994,0x110a67600) malloc: *** error for object 0x7ff7bb760760: pointer being freed was not allocated
But I don't know why.
#include <iostream>
#include <random>
#include <ctime>
using namespace std;
int main()
{
default_random_engine gen(time(0));
uniform_int_distribution<> dis(1, 100);
const int max = 20;
int* array[max];
// un tableau normal
int val[max];
for (int i = 0; i < max; i++) {
val[i] = dis(gen);
}
for (int i = 0; i < max; i++)
{
array[i] = &val[i];
}
//... modifying function on the array
// show the array
for (int i = 0; i < max; i++) {
cout << val[i] << " ";
}
// deleting pointeurs (problematic !!!!)
for (int i = 0; i < max; i++)
{ delete array[i];}
delete[] array;
return 0;
}
Could you help me, please?
delete operator must be used only on a dynamically allocated memory (with the new).
In your case you have an array int val[max]; with automatic storage duration. And array of pointers int* array[max]; also with automatic storage duration.
Automatic storage duration means memory for arrays int val[max]; and int* array[max]; will be allocated when execution enter in the scope they declared and will be freed when execution lives the scope (at your case main function).
But when you trying to call delete array[i]; you force compiler to attempt clear element from int val[max] onto which array[i] pointing to. But it can't do that because this value never have been allocated on the heap with new.
// Edit
As you mentioned in comment to this answer you added changes to your code:
int **array = new int*[max];
for (int i=0; i < max; i++) {
array[i] = new int;
}
An still have the same error;
The reason behind it most likely is that you still have this cycle
for (int i = 0; i < max; i++) {
array[i] = &val[i];
}
int** array; item: array[i] - is a pointer.
You allocated memory on the heap and stored address of this memory into that pointer:
array[i] = new int;
Lets say new int; returned address ADDRESS_FROM_HEAP
Then you took address of int val[max]; by &val[i] and assigned it to the pointer array[i] = &val[i];
Lets say &val[i] equal to ADDRESS_FROM_STACK
Then you trying to delete array[i];
But at this moment array[i] == ADDRESS_FROM_STACK;
Not only delete unable to free memory on ADDRESS_FROM_STACK, you also lost ADDRESS_FROM_HEAP and memory by this address will not be freed.
If you would change your loop to this
for (int i = 0; i < max; i++) {
*array[i] = val[i];
}
You will store a COPY of val[i] in the memory pointed by array[i] pointer.
But by looking at your code I can't honestly see why you allocate any memory dynamicly.
If you will just leave code as it is in your original question and just remove all delete statements, it will work just fine.

How to delete pointer from a dynamic array of pointers at an exact index?

When we have dynamic array of pointers in hand, suppose we want to delete 3rd index of this array and copying the higher pointers down one slot.
Q1: Do we need to delete 3rd element?
Q2: What happens after we make delete aPtr[3] and assigning new pointer to aPtr[3]
Does the code part do what I am trying to do?
'''
A **aPtr = new A*[10];
for(int i=0; i< 10; i++)
{
aPtr[i] = new A;
}
delete aPtr[3];
for(int i=3; i<9; i++)
{
aPtr[i] = aPtr[i+1];
}
'''
Another question regardless of the previous one. When we want to delete all the elements in the array of pointers, is the statement "delete [] aPtr;" also required?
'''
A **aPtr = new A*[10];
for(int i=0; i< 10; i++)
{
aPtr[i] = new A;
}
for(int i=0; i<10; i++)
{
delete aPtr[i];
}
delete[] aPtr; //<-----Is this line required to free the memory?
'''
Your code looks good with one exception.
delete aPtr[3];
for(int i=3; i<9; i++)
{
aPtr[i] = aPtr[i+1];
}
Add this:
aPtr[9] = nullptr;
Otherwise aPtr[8] and aPtr[9] both point to the same place, and later when you delete the whole thing, you'll double-delete that pointer.
Otherwise, it looks good.

memory leak in a 2D array with pointers

I have a function using a 2D array and I want to copy data from one array to another and I used a tmp array, but valgrind kept on saying I have memory leak. I can't figure out why. The following is part of a function.
// valgrind gave me error as operator new[] (unsigned long) for the following line
T** temp_pointer = new T*[rows];
for (int i=0; i < rows; i++) {
temp_pointer[i] = new T[columns];
}
for (int i =0; i< rows; i++) {
for (int j =0; j < (columns-3); j++) {
temp_pointer[i][j] = Arry[i][j];
}
temp_pointer[i][columns -3 ] = myvalue1;
temp_pointer[i][columns-2] = myvalue2;
temp_pointer[i][columns-1] = myvalue3;
}
for ( int i =0; i< rows; i++)
delete [] Arry[i];
delete [] Arry;
Arry= temp_pointer;
I also have a destructor which recursively delete the Arry pointers. Arry is private member of a template class.
I just could not figure out why it was a memory leak. Am I supposed to recursively delete temp_pointer ?? (I tried and it didn't work)
I just didn't know where did it leak?
It is not entirely clear why valgrind claims that the memory is being leaked, but you clearly have an out of bound access in your loop.
temp_pointer[i][columns] = myvalue;
The index of the last element of an array is not its size, it is (size-1). Writing into a location outside of the array's bound could clobber the memory allocator's housekeeping information and cause valgrind to complain.

Deleteing 2D array correctly?

My question arises from this answer.
In the comments he mentions that I should delete the allocated dynamic 2D array in the reverse order.
However I did not understand much why this should be done. Here is the code:
//intialising array
int size = 10000;
double **array = new double[size];
for(int i = 0; i < size; i++)
array[i] = new double[size];
//conventional de-initialise
for(int i = 0; i < size; i++)
delete[] array[i];
delete[] array;
//reverse de-initialise
for(int i = size - 1; size >= 0; i--)//notice reverse order here
delete[] array[i];
delete[] array;
So my question is, is there any significant difference between the 2 methods of de-allocating a 2D array?
In your example there's no difference - you create 100K pointers, and then allocate memory for each. It doesn't matter how you allocate/deallocate memory and assign it to pointers array.
However your question is about why reverse deallocation was in another post, and opposite to your example it matters - counter variable is reused to countdown from last allocated object down to 0, when new memory allocation failed. If deallocating other direction you'd need additional variable there:
try
{
array = new double*[size];
// Don't shadow counter here.
for(counter = 0; counter < size; counter++)
{
array[counter] = new double[size];
}
}
catch(std::bad_alloc)
{
// delete in reverse order to mimic other containers.
for(--counter; counter >= 0;--counter)
{
delete[] array[counter];
}
delete[] array;

Segmentation Fault C++

I am getting a "Segmentation fault (core dumped)" run-time error with the following code:
#include <iostream>
#include "Student.h"
#include "SortedList.h"
using namespace std;
#define BOUNDS 100
int main() {
SortedList *list = new SortedList(); // points to the sorted list object
Student *create[BOUNDS]; // array to hold 100 student objects
int num = 100000; // holds different ID numbers
// fills an array with 100 students of various ID numbers
for (int i = 0; i < BOUNDS; i++) {
create[i] = new Student(num);
num += 10;
}
// insert all students into the sorted list
for (int i = 0; i < BOUNDS; i++)
list->insert(create[i]);
// individually deletes each student
num = 100000;
for (int i = 0; i < BOUNDS; i++) {
delete list->find(num);
num += 10;
}
// insert all students into the sorted list
for (int i = 0; i < BOUNDS; i++)
list->insert(create[i]);
num = 100000;
for (int i = 0; i < BOUNDS; i++) {
list->remove(num);
num += 10;
}
cout << "test2" << endl;
delete list;
return 0;
}
I have narrowed the error down to the delete list; lines (or whichever one comes first). I am just wondering as to why this is and how to possibly fix it. Any insight on this matter would be useful.
You have two problems that I can see.
First, in this loop:
for (int i = 0; i < BOUNDS; i++) {
x = new Student(num);
num += 10;
}
You are creating a bunch of dynamic Students and putting the latest one in x and the previous one is lost. This creates 100 Students dynamically and 99 of them are leaked. Also it doesn't fill an array with Students like the comment above it says it does. I'm not sure what you're trying to do here so I can't comment on what you need to do instead.
Secondly, you are calling delete here:
delete list->find(num);
on Students that are in automatic storage (the stack) (because you filled the list with pointers to the Students in create which holds automatic Students), which leads to undefined behaviour and is probably the cause of your segfault. You don't need to deallocate these Students because they will be deallocated when the array goes out of scope at the end of main.
Without knowing how StudentList is implemented, this is kind of shot in the dark but...
list->insert(&create[i]); is adding a stack allocated object to the list, and then delete list->find(num); tries to delete this stack allocated object. You can't delete stack allocated objects.
In addition to this, your first for loop is leaking memory.
And I've been ninja'd.
This line has a problem:
list->insert(&create[i]);
At that point, create has been allocated, but nothing has been put into it. Probably the result of x = new Student(num) should be assigned there.
"create" array is allocated on stack. You are trying to delete stack allocated memory that's why you getting this error.
delete list->find(num);
You are definitely leaking memory:
// fills an array with 100 students of various ID numbers
for (int i = 0; i < BOUNDS; i++) {
x = new Student(num);
num += 10;
}
The x is leaked in this snippet, unless the ctor of Student somehow magically inserts itself somewhere, where the pointer can be tracked.
And that might or might be related to the crash.