Memory Leak, source: float** binsRowPtrs = new float *[_nbins]; - c++

How do I delete this properly?
float** binsRowPtrs = new float *[_nbins];
The items are not dynamic created with new.
float** binsRowPtrs = new float *[_nbins];
for (int i = 0; i < _nbins ;i++)
{
binsRowPtrs[i] = (float*) (bins[i].row(y).data);
}

How do i delete this properly[?]
Properly? You use RAII and let something else handle the deletion for you. Depending on what you're trying to do, you may want to use:
std::vector<std::vector<float>>: an array of arrays of floats;
std::vector<float*>: an array of non-owning pointers to floats (i.e. something else handles correct allocation and deallocation);
or maybe just std::vector<float>: an array of floats.

The rule is:
Call as many delete or delete[] respectively as new or new[] you used and on the exact same addresses.
So if you just called new on binRowPtrs then you just need to call delete binRowPtrs.
However, in the part of your code which you didn't show us, If you used dynamic allocation through new for each of the array elements then you need to loop through the array and call delete on each of the element as well.
Note that ideally,
In C++ You should use dynamic allocations only when you cannot avoid them &
If et all you must, never use raw pointers, always use RAII through smart pointers to avoid the explicit memory management(you already noticed the perils of doing so in your case).

This will clear those pointers:
delete [] binsRowPtrs;
But the actual data you are storing with bins won't be touched.

Related

Trying to deallocate a dynamic array of std::forward_list pointers (C++)

I'm trying to deallocate a dynamically allocated array of pointers to forward lists that was created with something like:
deck = new forward_list<T>*[numDecks];
for (int i = 0; i < numDecks; i++) {
deck[i] = new forward_list<T>;
}
numberOfDecks = numDecks;
I tried to iterate and delete the decks like this:
for (int i = 0; i < numDecks; i++) {
delete[] deck[i];
numberofDecks--;
}
delete[] deck;
But I got a read access violation. In fact, even if I just write:
delete[] deck[0];
I still get a read access violation. I've been playing around with this for quite some time and haven't been able to get it to work. I'm attaching a screenshot of the error (it appears in the forward_list file.
Thank you.
delete[] is for deleteing something that was allocated via new []. When you allocated something via new you need to delete it via delete.
There is no apparent reason for any manual dynamic allocations in your code. The std::forward_list already manages the memory of its elements. Storing pointers in the list has no advantage unless you need a level of indirection for some reason. And if you need it you should use smart pointers not raw ones. Also allocating the std::forward_list itself dynamically is most likely not needed (and again: use smart pointer if you do).
Your code has undefined behavior, as you are creating the std::forward_list objects using new but then destroying them with delete[] instead of delete. You need to change this:
delete[] deck[i];
To this:
delete deck[i];
new/delete are for single objects, and new[]/delete[] are for arrays. They must be matched up properly.
A better option is to use std::vector<std::forward_list> instead of std::forward_list*[], and let the vector handle the memory for you.

Better way to store the address and value of a pointer, and reuse that same pointer variable without using dynamic memory allocation

Sorry if this question is already answered somewhere else, but I've been searching for a couple days and haven't been able to find exactly what I'm looking for.
I was wondering what a safer/cleaner way is to store a pointer (keep the address and value the same and store in some container) and reuse that same pointer variable.
Currently, I'm just using dynamic memory allocation and manually deleting it later on, but I was wondering if there is a better way to do this (I'll elaborate more after the code, since it may be easier to understand what I'm asking for then).
I attached some sample code below with what I'm talking about, and how I am currently doing it (please bear with me on any glaring mistakes, I'm still learning C++):
struct MyStruct{
double* arr;
MyStruct* parent_struct;
};
MyStruct* first_struct = new MyStruct;
first_struct->arr = some_array;
first_struct->parent_struct = nullptr;
std::vector<MyStruct*>* my_vector = new std::vector<MyStruct*>();
my_vector->push_back(first_struct);
double* temp_array;
MyStruct* temp_struct;
MyStruct* previous_struct;
for (i=0; i<num_iterations; i++){
temp_array = new double[sizeofarray];
assign_some_values(temp_array);
assign_struct_some_values(previous_struct);
if (some_condition(temp_array)){
temp_struct = new MyStruct;
temp_struct->arr = temp_array;
temp_struct->parent_struct = previous_struct;
my_vector->push_back(temp_struct);
} else{
delete [] temp_array;
}
}
... use values in my_vector ...
for (j=0; j<my_vector.size(); j++){
delete [] (*my_vector)[j]->arr;
delete (*my_vector)[j];
}
delete my_vector;
The main thing is, what alternative to the dynamically allocated arrays/structures can I use?
Please keep in mind that I would like to try to keep the address and values the same once they are added to my_vector, if at all possible (due to some requirements with the code I'm using). I feel like there is a much better way to do this without dynamic memory allocation, or so many pointers (like using smart pointers, std::array, etc), but I haven't been able to properly get any of the other methods to work.
When I try using smart pointers, I can't seem to get the custom deleter to work properly for the structures.
And when using a container (like std::vector) for the arr variables instead of double*, they keep getting deallocated (or I'm accidentally changing the address/values somehow) before the for loop is finished.

When should I use delete? (Consequences of not deleting after a dynamically created 2d array)

I am new to dynamic allocation and pointers. I will try to fill out a 2D dynamic array from a file and then apply a maze-solving algorithm (wall follower)on it.
Assuming I create a dynamically allocated 2D array like this:
int** board;
board = new int* [rowsize];
for(int row = 0; row < rowsize; row++)
{
board[row] = new int[colsize];
}
If I know that I won't be using this pointer for another variable, can I get away with not using delete for board ? If not what could potentially go wrong (If you are familiar with the wall follower algorithm) ? Also how do I delete a pointer to a pointer, would delete board be sufficient?
can I get away with not using delete for board?
Yes, but not for very long: repeated failure to delete arrays that your program allocates is a memory leak that eventually runs your process out of memory.
how do I delete a pointer to a pointer, would delete board be sufficient?
No, you will need to delete each pointer that you allocated and stored inside board:
for(int row = 0; row < rowsize; row++) {
delete[] board[row];
}
delete[] board;
Note square brackets after delete to indicate that you deleting an array, they are very important.
Allocating an deallocating memory for a rectangular matrix is a solved problem in C++ library. Switch to using a vector of vectors to avoid dynamic resource allocations:
std::vector<std::vector<int>> board(rowsize, std::vector<int>(colsize, 0));
If you don't delete the arrays you allocated they will continue to consume memory until the program is terminated. This might not technically be wrong, but it is wasteful.
With regard to deleting the board - no, it is not enough. You should delete every pointer you allocate with new:
for(int row = 0; row < rowsize; row++)
{
delete[] board[row];
}
delete[] board;
What you need to delete is the memory you allocated with new. That means that you don't deallocate the pointer itself, but the heap's memory it is pointing at.
So, you only need to do delete[] board. This will free up the int* array. It is not strictly necessary to use [] in this case, since it is a fundamental type array, but it is good practice to use it always for arrays, so you won't mess up when it's not like that.
Calling delete[] on an array will call the destructors of all objects inside the array itself, as well as freeing up the array. It is not necessary however for fundamental types.
Also note that you don't need to free the int** board. The pointer are variables like any other with some special capability, but they are allocated in the stack just like any other when you declare them like that.
Hope it helps :)

Is this deallocation correct?

Is this deallocation correct ?
vSize -> Dynamically the values will change for each and every run
// Allocation
int* xDump = new int(vSize);
int* yDump = new int(vSize);
// Deallocation
delete xDump;
delete yDump;
Is this deallocation correct?
This is correct, as long as this:
int* xDump = new int(vSize);
int* yDump = new int(vSize);
was not supposed to be this:
int* xDump = new int[vSize];
int* yDump = new int[vSize];
If you are using square brackets, you're dynamically allocating an array. In this case, you would need to use the delete[] keyword. Like so:
delete[] xDump;
delete[] yDump;
EDIT:
If you really wanted a dynamically allocated array, it is recommended to use a std::vector, over creating one with new/delete.
For example, here's how you would use a vector in your situation:
std::vector<int> xDump(vSize);
std::vector<int> yDump(vSize);
// no need for delete[]
You should avoid owning pointers (pointers that point to memory allocated on the heap), instead try to use smart pointers, or the containers, in your code where necessary. As both smart pointers and containers take advantage of the very useful RAII pattern, which will reduce programmer errors (i.e. less chances of memory leaks) and increase exception safety.
It seems that you are trying to allocate an array of ints, in which case it should be:
int* xDump = new int[vSize];
int* yDump = new int[vSize];
and
delete [] xDump;
delete [] yDump;
Yes, it is correct. No problems there.
You need to call delete [] if you intend to delete an array which does not seem to be the case here. but if parameter vSize is in square brackets [] (may be you want this?) and then you definitely should call delete []
This construct:
int* xDump = new int(vSize);
is equivalent to:
int* xDump = new int;
*xDump = vSize;
...the answer is yes, it is correct, because you are not allocating an array.

How do I set a pointer to Null at run-time (C++)

Right now I have a pointer set to a row in my 2D array. I want that pointer to stop pointing to that row, but I will be using the pointer later for something else. I just want to know how to unset the pointer after it is initialized and has pointed to a row.
double* tempRow;
tempRow = (double*) malloc(size * sizeof(double));
...
tempRow = NULL;
doesn't unlink the tempRow variable from the array row. Why not?
I wonder if I should be using C then instead. Will there be overhead when using a vector?
While you have written will set tempRow to NULL, it wont release the memory you have allocated. For that you need
free(tempRow);
tempRow = NULL;
However if you're using C++ as the tags suggest, you'd be better off using C++ new/delete
double* tempRow;
tempRow = new double[size];
...
delete [] tempRow;
tempRow = NULL;
you can even use the STL to handle your memory allocation for you.
std::vector<double> tempRow(size);
// You can access the data, in a similar way to an array
tempRow[5] = tempRow[4]+tempRow[3];
// If you really need to access the underlying pointer, (To pass to another
// function for example) you can do this. Note that the pointer will be valid
// until the vector is destroyed or modified in certain ways that can cause the
// vector to reallocate its memory. So you can't use this to pass data to a
// function that destroys or takes ownership of the passed in pointer.
fn_requiring_pointer( &temp[0] );
// The memory used in tempRow will get cleaned up automatically when the
// object goes out of scope
//
// If I really need to free up the memory used in it early I can use a swap
// hack. (iirc tempRow.clear() isn't guaranteed to release the memory)
std::vector<double>().swap(tempRow); // Unneeded in most cases.
Also trying to reuse the tempRow pointer for something unrelated is probably not necessary. Just create a new pointer with a different name. Reusing a variable form multiple different unrelated purposes can make code very hard to understand later.
I'm new at C++ as well, but a while ago, someone told me that using std::vector is a much safer approach to handling arrays of data.
Automatic re-allocation when adding more elements.
Iterators for use with stuff from #include <algorithm>.
Bounds-protection with .at(index) element access.
No messy pointer-tracking required.
C-array style access with operator[].
RAII.
You would declare a vector like this:
std::vector<double> tempRow(size);
tempRow[0] = 3.00;
tempRow[1] = 1.00;
// no need to use delete[] or free(), it will destruct itself
// and relinquish its resources automatically.
The example you've shown should work.Also if you've not freed the memory before making temRow NULL, you are leaking memory.
double* tempRow;
tempRow = (double*) malloc(size * sizeof(double));
...
free(tempRow); // free the memory.
tempRow = NULL; // reset the pointer.
...
tempRow = &some_other_double_var; // reuse the pointer.
Doesn't seem to work?
That's the worst complaint and a solution providers's nightmare.
Do you mean you get a compilation error?
If yes, did you include <cstdio>? and using namespace std;
Doesn't work in what way? The normal way to "unset" a pointer in C++ is with:
tempRow = 0;
but what you have should be fine, assuming you've included the correct headers or otherwise have the correct definition for NULL.
As an aside, you should first call free() on that memory before losing the pointer, otherwise you'l have a memory leak (and this is assuming you have a good reason to use C-style malloc/free instead of the more kosher C++ new/delete).