简体   繁体   中英

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 ;

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.

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 new s throws then you'll have a leak. Try using std::vector instead.

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);
    }
}

Yes, you use pointer addition, but you need to understand how the memory is laid out. Say x is a pointer to the first element of an array of ints, if you want to access x[2], you can use *(x+2). However, with matrices it can get quite confusing and you're a lot more likely to access wrong indices in your matrix if you do this, so I wouldn't advise it.

You could do *(*(matrix+i)+j) . It should be equivalent to bracket notation. What is happening with both notations is simply pointer arithmetic .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM