Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

De-allcoating dynamically allocated multidimensional arrays.

So, I have this code, and I am trying to deallocate the array ppint at the end. I have tried using leaks with Xcode to figure out if it is working, but I don't quite understand it. Will doing this work?

delete ppint[0];
delete ppint[1];
delete ppint[2];
delete ppint[3];

Or is there something else that must be done?

#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;

int main()
{
    int **ppint;
    ppint = new int * [4];

    for(int i = 0; i < 4; i++ ) {
        ppint [i] = new int[4];
    } // declares second layer of arrays

    for(int i = 0, count = 0; i < 4; i++ ) {
        for(int j = 0; j < 4; j++ ) {
            count++;
            ppint [i] [j] = count;
        } //init part 2
    } // init array

    for(int i = 0; i < 4; i++ ) {
        for(int j = 0; j < 4; j++ ) {
            cout << ppint [i] [j] << endl;
        } // print part 2
    } //print array
}
like image 735
MarJamRob Avatar asked Jun 09 '26 16:06

MarJamRob


2 Answers

Close. You would have to use delete[] because you allocated each of them with new[]:

delete[] ppint[0];
delete[] ppint[1];
delete[] ppint[2];
delete[] ppint[3];

But of course, you should use a loop:

for(int i = 0; i < 4; i++ ) {
  delete[] ppint[i];
}

And then don't forget to delete[] ppint itself:

delete[] ppint;

However, in C++, we prefer to not mess around with dynamically allocated arrays. Use a std::vector<std::vector<int>> or a std::array<std::array<int, 4>, 4>. If you care about locality of data, try boost::multi_array.

like image 103
Joseph Mansfield Avatar answered Jun 11 '26 05:06

Joseph Mansfield


My solution would be:

#include<iostream>
#include<cstdlib>

using namespace std;

int main(){

    int ** twod;
    twod = new int*[4];
    int counter = 0;
    /*init 2d variable and check whether we got the memory*/
    if ( twod == NULL) {
        exit(EXIT_FAILURE);
    }
    for (unsigned i = 0; i< 4; i++){
        /**/
        twod[i] = new int[4];
        if (twod[i] == NULL){
            exit(EXIT_FAILURE);
        }
        for (unsigned j = 0; j < 4; j++){
            counter++;
            twod[i][j]=counter;
        }
    }

    for ( unsigned i = 0; i < 4; i++){
        for (unsigned j = 0; j < 4; j++){
            cout << twod[i][j] << endl ;
        }
    }

    for (unsigned i = 0; i < 4; i++)
        delete [] twod[i];

    /*and don't forget to delete the int* array as well.*/
    delete [] twod;

}

if you want to make sure you didn't make any memory errors use valgrind as well:

Valgrind is an excellent tool for detecting memory errors. In the output it show we made 5 memory allocations which were all freed. Valgrind can also show other kinds of memory errors like use of memory which you didn't allocate at all. Using memory that was not properly initialized before use, like i said an excellent memory check tool.

$ valgrind ./a.out
==18376== Memcheck, a memory error detector
==18376== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==18376== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==18376== Command: ./a.out
==18376== 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
==18376== 
==18376== HEAP SUMMARY:
==18376==     in use at exit: 0 bytes in 0 blocks
==18376==   total heap usage: 5 allocs, 5 frees, 96 bytes allocated
==18376== 
==18376== All heap blocks were freed -- no leaks are possible
==18376== 
==18376== For counts of detected and suppressed errors, rerun with: -v
==18376== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

And ofcourse as others are telling you make use of the std::vector for example you are coding in c++ not c.

like image 37
hetepeperfan Avatar answered Jun 11 '26 07:06

hetepeperfan