Splitting dynamically allocated multidimensional arrays.

So I have this code and I am trying to free the array ppint

at the end. I tried leaking with Xcode to find out if it works, but I don't quite get it. Will it do it?

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

      

Or is there something else that needs to 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
}

      

+3


source to share


5 answers


Close. You should use delete[]

because you have highlighted each one with new[]

:

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

      

But of course you have to use a loop:

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

      



And then don't forget yourself delete[]

ppint

:

delete[] ppint;

      

However, in C ++, we prefer not to tamper with dynamically allocated arrays. Use std::vector<std::vector<int>>

or std::array<std::array<int, 4>, 4>

. If you need data locality, give it a try boost::multi_array

.

+6


source


My decision:

#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 prevent you from making memory errors use valgrind:



Valgrind is a great tool for detecting memory errors. In the output, this shows that we have allocated 5 allocated memory. Valgrind can show other types of memory errors as well, such as using memory that you didn't allocate at all. Using memory that was not properly initialized before use, for example, I said a great memory checker 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 as others say, you are using std :: vector, for example, you are coding in C ++, not c.

+2


source


You still need to delete the memory it points to ppint

. You also need to use delete[]

and not delete

.

However, prefer the standard container over manual arrays.

std::vector< std::vector<int> > iv; // dynamic size
std::array< std::array<int,4>, 4> ia; // static size

      

+1


source


Something allocated with new[]

must be freed with delete[]

. But use and std::vector

instead of raw arrays new

. It automatically manages memory for you.


The following emulates your source code directly and is shorter, cleaner and safer:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<vector<int>> v( 4, vector<int>( 4 ) );

    for( int i = 0, count = 0; i < 4; ++i ) {
        for( int j = 0; j < 4; ++j ) {
            ++count;
            v[i][j] = count;
        }
    }

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

      


In the spirit of C ++, you can / should define a reusable matrix class like

#include <iostream>
#include <vector>
using namespace std;

template< class item_t >
class matrix_
{
private:
    vector<item_t>  items_;
    int             width_;
    int             height_;

    int index_for( int const x, int const y ) const
    {
        return y*width_ + x;
    }

public:
    item_t const& operator()( int const x, int const y ) const
    {
        return items_[index_for( x, y )];
    }

    item_t& operator()( int const x, int const y )
    {
        return items_[index_for( x, y )];
    }

    matrix_( ssize_t const w, ssize_t const h )
        : items_( w*h )
        , width_( w )
        , height_( h )
    {}
};

int main()
{
    matrix_<int> m( 4, 4 );

    for( int i = 0, count = 0; i < 4; ++i ) {
        for( int j = 0; j < 4; ++j ) {
            ++count;
            m( j, i ) = count;
        }
    }

    for( int i = 0; i < 4; ++i ) {
        for( int j = 0; j < 4; ++j ) {
            cout << m( j, i ) << endl;
        }
    }
}

      

+1


source


You need one call delete

for every previous callnew

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

      

+1


source







All Articles