Home > Enterprise >  Deallocate contiguous block of memory for a 2D array
Deallocate contiguous block of memory for a 2D array

Time:11-30

I understand I'm splitting the array over the double pointer, but how can I deallocate if I lost the data track?

#include <stdio.h>
#include <stdlib.h>

#define width 20
#define height 20

void allocate_matrix(int ***matrix)
{
    double **local_matrix, *data;
    local_matrix = (double **)malloc(sizeof(double *) * height);
    data = (double *)malloc(sizeof(double) * width * height);
    for (int i = 0; i < height; i  )
    {
        local_matrix[i] = &(data[i * width]);
    }
    *matrix = local_matrix;
}

void deallocate_matrix(int **matrix) {
    
}

int main(void) {
    int **matrix;
    allocate_matrix(&matrix);
    deallocate_matrix(matrix);
    return 0;
}

CodePudding user response:

You didn't lose track of the second pointer. If you look at your loop body:

local_matrix[i] = &(data[i * width]);

When i is 0, local_matrix[0] is assigned &data[0] which is the same as data. So that's what you need to free:

void deallocate_matrix(int **matrix) {
    free(matrix[0]);
    free(matrix);
}

CodePudding user response:

First of all, you are allocating space for double then use it as int, which doesn't make sense (and will not compile).

But the main problem here is that you shouldn't be allocating this as fragmented segments but as a contiguous 2D array. Please study Correctly allocating multi-dimensional arrays. This will give a major performance boost and may (arguably) make the code a bit easier to read as well.

If we follow the advise in that post, then your code could be rewritten as:

#include <stdio.h>
#include <stdlib.h>

void allocate_matrix(size_t height, size_t width, int (**matrix)[height][width])
{
    int (*local_matrix) [height][width];
    local_matrix = malloc(sizeof *local_matrix);
    if(local_matrix == NULL)
    {
      // handle errors
    }
    *matrix = local_matrix;
}

int main (void) 
{
    const size_t height = 20;
    const size_t width  = 20;
    int (*matrix)[height][width];
    allocate_matrix(height, width, &matrix);

    int(*pmatrix)[width] = *matrix; // pointer to first 1D array for easier syntax
    for(size_t h=0; h<height; h  )
    {
      for(size_t w=0; w<width; w  )
      {
        pmatrix[h][w] = h w; // assign some sort of data
        printf("%d ", pmatrix[h][w]);
      }
      printf("\n");
    }

    free(matrix);
    return 0;
}

As you can see this also eliminated the need for a complex deallocation routine, since we can just pass the pointer directly to free() and deallocate everything at one single place.

CodePudding user response:

the following proposed code:

  1. needs the header file: stdlib.h for the prototypes for exit() and malloc() and EXIT_FAILURE
  2. performs the desired functionality
  3. you might want to modify the calculation of the initialization values of the matrix

and now, the proposed code:

double **allocate_matrix(void)
{
    local_matrix** = malloc( sizeof(double *) * height );
    if( ! local_matrix )
    {
        perror( "malloc for matrix height failed:");
        exit( EXIT_FAILURE );
    }
    
    for( size_t y = 0; y<height; y   )
    {
        local_matrix[y] = malloc( sizeof(double) * width );
        if( !local_matrix[y] )
        {
            //cleanup and exit
        }
        
        for ( size_t i = 0; i < width; i  )
        {
            local_matrix[y][i] = i;
        }
    }
    
    
    
    return local_matrix;
} 


int main( void )
{
    double **matrix;

    matrix = allocate_matrix();
    
    for( size_t y= 0; y< height; y   )
    {
        free( matrix[ y ] ):
    }
    free( matrix );
}
  • Related