Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Memory leaks with 2D fully dynamic array

I was given a task to implement a simple API for fully dynamic 2D array according to following interface.

const int m = 2;
const int n = 3;
int **array = allocate_array (m, n);
assert (array != NULL);
for (unsigned int i = 0; i < m; i++)
{
  for (unsigned int j = 0; j < n; j++)
  {
    array[i][j] = i*10 + j;
  }
}
print_array (array, m, n);
free_and_nullify_array (&array, m);
printf("array points to %p\n", array);

/*
OUTPUT: 
 0  1  2
10 11 12
array points to (nil)
*/

I need to implement only 3 specific functions as part of the program.

While I have made an attempt to implement these functions, the program is currently indicating the presence of memory leaks. Despite my efforts, I was unable to identify the exact locations within the code where these memory leaks are occurring.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

//! allocate an m x n fully-dynamic 2D array
int** allocate_array (int m, int n)
{
    int ** arr = malloc (sizeof(int *) * m);
    if (!arr)
    {
        free(arr);
        arr = NULL;
        return NULL;
    }
    
    for (int i = 0; i < n; i++)
    {
        arr[i] = malloc (sizeof(int) * n);
        if (!arr[i])
        {
            free(arr[i]);
            arr[i] = NULL;
            return NULL;
        }
    }
    
    return arr;
}

//! free *array, a full-dynamic 2D array with m rows
//! and set its pointer to NULL
void free_and_nullify_array (int ***p_array, int m)
{
    for (int i = 0; i < m; i++)
    {
        free((*p_array)[i]);
        (*p_array)[i] = NULL;
    }
    
    free(*p_array);
    *p_array = NULL;
}

//! print an m x n fully-dynamic array
//! use one line per row, 2 digits per integer ("%2d"), one space
void print_array (int **array, int m, int n)
{
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            printf("%2d ", array[i][j]);
        }
        printf("\n");
    }
}

>Solution :

For starters you have a typo in this for loop

for (int i = 0; i < n; i++)
                ^^^^^
{
    arr[i] = malloc (sizeof(int) * n);
    if (!arr[i])
    {
        free(arr[i]);
        arr[i] = NULL;
        return NULL;
    }
}

You need to use the variable m instead of n.

Another problem in this for loop is if a memory was not allocated successfully then the memory allocated previously for the array of pointers and for one-dimensional arrays of integers is not freed.

You should write for example

//! allocate an m x n fully-dynamic 2D array
int ** allocate_array( int m, int n )
{
    int **arr = malloc( m * sizeof( int * ) );

    if ( arr != NULL )
    {
        int i = 0;

        while ( i < m && ( arr[i] = malloc( n * sizeof( int ) ) ) != NULL ) i++;

        if ( i != m )
        {
            for ( int j = 0; j < i; j++ ) free( arr[j] );
            free( arr );
            arr = NULL;
        }
    }
    
    return arr;
}

In general you should check that values of the parameters are positive values. And instead of using the signed integer type int for the parameters it will be much better to use the unsigned integer type size_t.

For example

//! allocate an m x n fully-dynamic 2D array
int ** allocate_array( size_t m, size_t n )
{
    int **arr = NULL;

    if ( m != 0 && n != 0 )
    {
        int **arr = malloc( m * sizeof( int * ) );

        if ( arr != NULL )
        {
            size_t i = 0;

            while ( i < m && ( arr[i] = malloc( n * sizeof( int ) ) ) != NULL ) i++;

            if ( i != m )
            {
                for ( size_t j = 0; j < i; j++ ) free( arr[j] );
                free( arr );
                arr = NULL;
            }
        }
    }

    return arr;
}

And within the function free_and_nullify_array this statement

(*p_array)[i] = NULL;

is redundant. You may remove it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading