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
}
source to share
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
.
source to share
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.
source to share
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;
}
}
}
source to share