2

I have a 2D array like so:

    char * array[2][2];

I wanted it to store char *, so I tried to malloc() using:

    for(i=0:i<2;i++){
        for(j=0:j<2;j++)
        {
            array[i][j]=(char*)malloc(sizeof(char  *)*2);
        }
    }

After that, I stored some elements of char * in the 2D array, and the 2D array can print them out, which is fine.

I then tried to deallocate my 2D array using:

    for(i=0:i<2;i++){

        for(j=0:j<2;j++){
         
            free(array[i][j]);
        }
    }

When I run the program, I get a "free() : invalid pointer" message.

I tried using Valgrind, which reports that all my allocs and frees are accounted for. However it shows that I've "definitely lost" some bytes.

Any views or thoughts will help.

Here's a sample code to demonstrate what I'm talking about:

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

int main()
{   
    char * r0c0 = " hello ";
    char * r0c1 = " bye ";
    char * r1c0 = " this ";
    char * r1c1 = " is me ";
    
    int i=0;
    int j=0;
    for(i=0;i<2; i++)
    {
        for(j=0;j<2;j++)
        {
            *(*(array+i)+j) = (char *)malloc(sizeof(char *)*2);
        }
    }

    array[0][0]= r0c0;
    array[0][1]= r0c1;
    array[1][0]= r1c0;
    array[1][1]= r1c1;
    
    for(i=0;i<2;i++)
    {
        for(j=0;j<2;j++)
        {
            printf("%s\t",array[i][j]);
        }
        printf("\n");
    }

    for(i=0;i<2; i++)
    {
        for(j=1;j>=0;j--)
        {
            free(*(*(array+i)+j));
        }
    }
     
    return EXIT_SUCCESS;
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • The problem is somewhere in the code you haven't shown. For further assistance, prepare a [mcve] – Igor Tandetnik Oct 25 '20 at 15:29
  • This can't be the code you are actually compiling. It uses the name `array` that is never declared. – Igor Tandetnik Oct 25 '20 at 15:44
  • 1
    `array[0][0]= r0c0` This leaks any memory you have previously allocated and assigned to `array[0][0]`. Afterwards, `array[0][0]` points to the string literal, not to a block of memory allocated with `malloc`. Subsequent call to `free(array[0][0])` therefore exhibits undefined behavior. Drop the `malloc` loop and the `free` loop - this program doesn't need either. – Igor Tandetnik Oct 25 '20 at 15:46
  • 1
    `array[i][j]=(char*)malloc(sizeof(char *)*2);` uses a dubious allocation size – chux - Reinstate Monica Oct 25 '20 at 15:54
  • 1
    Please also decide for a programming language. For either of the two, your code is bad, but knowing your target language is key for making a proper suggestion how to improve it... Anyhow, as a new user, please take the [tour] and read [ask]. – Ulrich Eckhardt Oct 25 '20 at 15:59

1 Answers1

3

How to deallocate a 2D array of char pointers (?)

OP is de-allocating OK, yet not allocating and using the pointers well.


array[i][j]=(char*)malloc(sizeof(char *)*2); is incorrect. That allocates memory for 2 pointers, yet array[i][j] needs an allocation for so many char.

First, allocate enough for the strings:

//  *(*(array+i)+j) = (char *)malloc(sizeof(char *)*2);
#define STRING_SIZE_MAX 7   // size of longest string to get copied for this ap.
*(*(array+i)+j) = malloc(STRING_SIZE_MAX);

array[0][0]= r0c0; writes over the data just allocated, losing the original pointer and contributing the the error seen when attempting to free.

Instead, copy the contents of a string:

// array[0][0]= r0c0;
strcpy(array[0][0], r0c0);

Better: use the non-standard, but commonly available strdup() to allocate to the right size per string and copy the contents of the string. Otherwise, easy enough to write your own my_strdup().

 // int i=0;
  // int j=0;
  // for(i=0;i<2; i++) {
  //  for(j=0;j<2;j++) {
  //      *(*(array+i)+j) = (char *)malloc(sizeof(char *)*2);
  //  }
  //}

  // array[0][0]= r0c0;
  // array[0][1] = r0c1;
  // array[1][0]= r1c0;
  // array[1][1]= r1c1;

  array[0][0] = strdup(r0c0);
  array[0][1] = strdup(r0c1);
  array[1][0] = strdup(r1c0);
  array[1][1] = strdup(r1c1);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256