Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

2D dynamic memory allocation array in C++

A few days ago I learned about creating 2D allocated memory arrays from the internet, it works perfect. To access the array we just simply use matrix[i][j], however is there any way that I can dereference this 2D array by using * notation instead of [] for input as well as other methods?

First questions is solved I can use *(*(matrix + i) + j)

Now I got another question, last code segment is to free the allocated memory (I got it from internet as well), but I don't understand it, why cant I just use delete [] matrix ?

int **matrix;

// dynamically allocate an array
matrix = new int *[row]; 
for (int count = 0; count < row; count++)
{
    matrix[count] = new int[col];
}

// input element for matrix
cout << endl << "Now enter the element for the matrix..."; 
for (int i=0; i < row; i++) 
{
    for (int j=0; j < col; j++)
    {
        cout << endl << "Row " << (i+1) << " Col " << (j+1) << " :";
        cin >> matrix[i][j]; // is there any equivalent declaration here?
    }
}

// free dynamically allocated memory
for( int i = 0 ; i < *row ; i++ )
{
    delete [] matrix[i] ;   
}
delete [] matrix ;
like image 460
Casper Avatar asked Feb 12 '13 09:02

Casper


3 Answers

Answering your second question: when you allocate a 2D array with the following code

// dynamically allocate an array
    matrix = new int *[row]; 
    for (int count = 0; count < row; count++)
        matrix[count] = new int[col];

you are in fact allocating one array of pointers (your matrix variable, which is a double pointer) and "row" arrays of integers (each one representing one row in your matrix, of size "col"), which are matrix[0], matrix[1], etc. up to matrix[row-1].

Thus, when you want to free your matrix, you'll first need to free every single row (the arrays allocated within the loop), and then the array which held the rows. In your case, the code you use to free your matrix is partly wrong, and should be more like the following :

// free dynamically allocated memory
for( int i = 0 ; i < row ; i++ )
{
    //first we delete each row
    delete [] matrix[i] ;
}
//finally, we delete the array of pointers
delete [] matrix ;

The delete within the loop will free each row of your matrix, and the final delete will free the array of rows. In your code, you use delete row times on your double pointer (matrix), which makes no sense.

Finally, using a single delete on the double pointer is wrong, because it would end up in a memory leak as you aren't freeing the memory allocated for each row, only the pointers referring to it.

like image 82
JBL Avatar answered Oct 16 '22 20:10

JBL


Since a[b] is just *(a + b) you can of course do this:

*(*(matrix + i) + j)

Anyway, those new allocations are error prone. If one of the nested news throws then you'll have a leak. Try using std::vector instead.

like image 39
Pubby Avatar answered Oct 16 '22 18:10

Pubby


Something like this would work:

int **matrix;

// dynamically allocate an array
matrix = new (std::nothrow) int *[row];
if (matrix == NULL)
{
      // handle the error
}
for (int count = 0; count < row; count++)
{
    *(matrix + count) = new (std::nothrow) int[col];
    if (matrix[count] == NULL)
    {
          // handle the error
    }
 }

cout << "\nNow enter the element for the matrix..."; 
for (int i=0; i < row; i++)
{
    for (int j=0; j < col; j++)
    {
        cout << "\nRow " << (i+1) << " Col " << (j+1) << " :";
        cin >> *(*(matrix + i) + j);
    }
}
like image 2
SeedmanJ Avatar answered Oct 16 '22 19:10

SeedmanJ