How to properly deallocate memory for a 2d array in C++? - c++

Here's how I allocate it:
float** matrix = new float*[size];
for (int i = 0; i < size; i++) {
matrix[i] = new float[size];
}
And here's how I deallocate:
if (matrix != nullptr) {
for (int i = 0; i < size; i++) {
delete[] matrix[i];
}
}
free(matrix);
Is this correct or should I also delete[] the outer array?

delete[] is always paired with a new[].
delete is always paired with a new.
So yes, in your case, you need to call delete[] matrix; to release the array of float* pointers. Don't use free unless that pointer has been obtained with a call to malloc &c., which would be unusual in C++.
Although, if you want to model a matrix in the mathematical sense then might I suggest you use a 3rd partly library. I use BLAS, part of the Boost distribution.

How to properly deallocate memory for a 2d array in C++?
Not manually. Use an abstraction like std::vector that deallocates memory for you thanks to RAII, or std::array if you know the size of your matrix at compile-time.
{
std::vector<std::vector<float>> matrix(size);
for(auto& v : matrix) v.resize(size);
}
// memory automatically freed at the end of the scope
You should almost never use new and delete in Modern C++. Refer to my answer here for more information: Malloc vs New for Primitives
If you are writing a program that requires an high-performance matrix implementation, please do not create your own. Your code and my example using std::vector both have a cache-unfriendly jagged layout which can severely harm performance. Consider using an high-quality production-ready library such as Eigen, Blaze, or BLAS instead.

Related

Free dynamic array of static arrays?

I have code similar to this
EDIT this code is supposed to be on interface so only POD is allowed. No vectors, no containers.
int (*neco)[2];
int ahoj = 2;
neco = new int[ahoj+2][2];
int iter = 1;
for (size_t i = 0; i < 4; i++)
{
for (size_t j = 0; j < 2; j++)
{
neco[i][j] =iter;
iter++;
}
}
for (size_t i = 0; i < ahoj + 2; i++)
{
delete[] neco[i];
}
This does not work. The delete deletes memory not allocated.
Not even
delete[] neco;
Or any other delete. Everyone of them deletes memory BEFORE the allocated block.
Googling and consulting with peers in the office had no results. :)
How do I allocate dynamic array of "points" (two coordinates) and then free them?
I am able to solve the problem via using different structure.
But apperently I am able to allocate the memory. Write in the allocated memory…
How do I correctly free this memory? (Just accademic question.)
Plain pointers to dynamically allocated memory get you into troubles.
Use a std::unique_ptr:
#include <memory>
// ...
std::unique_ptr<int[][2]> neco(new int[ahoj+2][2]);
And remove that loop with delete[].
Alternatively, use std::vector<int[2]> neco(ahoj+2) - it does memory management for you and can be resized.
The general rule is that every new expression must be matched by a single corresponding delete expression.
Your new expression is the right hand side of the statement
neco = new int[ahoj+2][2];
so the corresponding delete expression is given in the statement
delete [] neco;
If that doesn't work (which is what you claim) it means the problem is in some other code exhibiting undefined behaviour.
Your loop
for (size_t i = 0; i < ahoj + 2; i++)
{
delete[] neco[i];
}
is incorrect because none of the neco[i] are the result of a new expression. So delete [] neco[i] has undefined behaviourin every loop iteration.
Given that your code sample(s) and description are incomplete, I doubt anyone else can give more useful advice.
Also, you are mistaken in your belief that you can't use a standard container. You can.
#include <vector>
int main()
{
std::vector<int[2]> avec(ahoj + 2);
int (*neco)[2] = &avec[0];
for (size_t i = 0; i < ahoj + 2; ++i)
{
for (size_t j = 0; j < 2; ++j)
{
neco[i][j] = iter;
++iter;
}
}
}
The only difference is that avec does the dynamic memory allocation and deallocation for you. neco is still a pointer to an array as required (according to your description) by your API. The two constraints on this approach are;
don't resize theavec after initialising neco (or reinitialise neco whenever avec is resized)
don't use neco after avec ceases to exist (since the behaviour will then be undefined).
Also, none of the arrays are actually static. So your question is mistitled.
If I can recall properly, an array of arrays (being dynamic or static), is basicly a matrix.
So, the academic answer:
The same way you allocate memory (first allocate the memory of the array of arrays, then with a foryou allocate the memory of the arrays inside the array), to free it, you need to delete in a forthe memory of the arrays, and then, in a simple delete, free the memory of the dynamic array.
So:
arrayOfArrays[[array1][array2][array3][array4]]
means: allocate memory of arrayOfArrays, then in a loop, allocate memory of array(number)
Same goes the other way around.
Free memory of arrayOfArraysin a single sentence.

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 :)

access violation in deleting a 2d array

I have a 2d array of object pointers, and I am trying to write a deallocator for an object that to delete both the pointers in the array, and then delete the array itself. I define the array in the header of the object to be destructed like so
space* board[6][6];
I allocate the space objects in the array like so:
board[0][0]= new space(1,0);
board[0][1] = new space(1, 0);
board[0][2] = new space(1, 0);
My current destructor is like this
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j){
delete board[i][j];
}
delete[] board[i];
}
delete[] board;
When I do this, I get this message: Unhandled exception at 0x5080A9E8 (msvcr120d.dll) in Blitz.exe: 0xC0000005: Access violation reading location 0xFEEEFEE2.
I'm not quite sure what to do, I've tried looking around, and it seems like my destructor should be okay. I know if I had a decent programming education, I would use something better, like a vector or something else. I downloaded a pdf on how people actually use C++ these days, and I'll probably go over that soon, but I would just rather just take care of this memory leak and move on.
The board and board[i] variables should not be deleted because they have not been allocated by new.
You are mixing new with delete[]. The behaviour of your program is therefore undefined.
It would be marginally better if you used std::vector<std::vector<space>> instead. Then, the memory management would be done for you.
But if you're modelling a matrix then this is also not a good choice: it will have a "jagged edge" and the memory allocated is not contiguous.
A good alternative would be to allocate a contiguous block and use the convention (i * rows + j) for the element at (i, j). A std::vector<space> would suffice. Then consider using a 3rd party matrix library like BLAS (www.boost.org).

Ways to tell if you have successfully released dynamic allocated memory

This is how i allocate dynamic memory for a 2D array
char **twod;
twod=new char*[count];
for (int i = 0; i < count; i++)
{
twod [i] = new char [MAX];
}
This is how i release the memory for a 2D array
for (int i=0; i<count;i++)
{
delete [] twod [i];
}
delete [] twod;
How do i know i have successfully released everything and there is no memory leak???
Ways to tell if you have successfully released dynamic allocated memory
Run the code in valgrind or any such memory leak detection tool.
If you want you could also overload the new and delete operators for your class and do the bookeeping yourself but that it too much effort so you are much better off setting with a memory leak detection tool.
Ofcourse I consider the example only an sample example and not the code one will usually go for because:
You are better off avoiding dynamic allocations, use automatic variables instead.
If you must then use smart pointers with RAII and not raw pointers.

Dynamic allocation with C++'s "placement new"

The question: How to use "placement new" for creating an array with dynamic size? or more specifically, how to allocate memory for array elements from a pre-allocated memory.
I am using the following code:
void* void_array = malloc(sizeof(Int));
Int* final_array = new(void_array) Int;
This guarantees that the final_array* (the array pointer) is allocated from the place that is reserved by void_array*. But what about the final_array elements? I want them to be allocated from a pre-allocated memory as well.
P.S: I have to say that I'm using some API that gives me some controls over a tile architecture. There is a function that works exactly like malloc, but also have other features, e.g. lets you control the properties of the allocated memory. So, what i basically need to do, is to use that malloc-like function to allocate memory with my desired properties (e.g. from which memory bank, to be cached where and etc.)
First off, let's make sure we all agree on the separation of memory allocation and object construction. With that in mind, let's assume we have enough memory for an array of objects:
void * mem = std::malloc(sizeof(Foo) * N);
Now, you cannot use placement array-new, because it is broken. The correct thing to do is construct each element separately:
for (std::size_t i = 0; i != N; ++i)
{
new (static_cast<Foo*>(mem) + i) Foo;
}
(The cast is only needed for the pointer arithmetic. The actual pointer required by placement-new is just a void pointer.)
This is exactly how the standard library containers work, by the way, and how the standard library allocators are designed. The point is that you already know the number of elments, because you used it in the initial memory allocation. Therefore, you have no need for the magic provided by C++ array-new, which is all about storing the array size somewhere and calling constructors and destructors.
Destruction works in reverse:
for (std::size_t i = 0; i != N; ++i)
{
(static_cast<Foo*>(mem) + i)->~Foo();
}
std::free(mem);
One more thing you must know about, though: Exception safety. The above code is in fact not correct unless Foo has a no-throwing constructor. To code it correctly, you must also store an unwind location:
std::size_t cur = 0;
try
{
for (std::size_t i = 0; i != N; ++i, ++cur)
{
new (static_cast<Foo*>(mem) + i) Foo;
}
}
catch (...)
{
for (std::size_t i = 0; i != cur; ++i)
{
(static_cast<Foo*>(mem) + i)->~Foo();
}
throw;
}
Instead of using a custom malloc, you should overwrite operator new() and use it. This is not operator new; there is a function actually called operator new(), confusing as it may seem, which is the function used by the normal (non-placement) operator new in order to get raw memory upon which to construct objects. Of course, you only need to overwrite it if you need special memory management; otherwise the default version works fine.
The way to use it is as follows, asuming your array size will be size:
Int* final_array = static_cast<Int*>(size == 0 ? 0 : operator new(sizeof(Int) * size));
Then you can construct and destroy each element independently. For instance, for element n:
// Create
new(final_array + n) Int; // use whatever constructor you want
// Destroy
(final_array + n)->~Int();