Rahul Rahul - 2 months ago 18
C Question

How can I pass a pointer to create a 2-D array on heap?

I learnt to create heap allocation of 2-D char array and initialize it.

Method 1:

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

int main()
{
char ** arr;
arr = (char **) malloc(2 * sizeof(char *));
arr[0] = (char *) malloc(256 * sizeof(char));
arr[1] = (char *) malloc(256 * sizeof(char));

sprintf(arr[0], "%s", "This is string 1");
sprintf(arr[1], "%s", "This is string 2");

int i;
for(i = 0; i < 2; i++)
{
printf("%s\n", arr[i]);
}

return 0;
}


But I'm trying to learn is to pass the pointer to a function to create a 2-D array, but in vain.

Method 2:

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

void test(char *** ptr);

int main()
{
char ** arr;
test(&arr);

sprintf(arr[0], "%s", "This is string 1");
sprintf(arr[1], "%s", "This is string 2");

int i;
for(i = 0; i < 2; i++)
{
printf("%s\n", arr[i]);
}

return 0;
}

void test(char *** ptr)
{
**ptr = (char **) calloc(2, sizeof(char *));
*ptr[0] = (char *) malloc(256 * sizeof(char));
*ptr[1] = (char *) malloc(256 * sizeof(char));
}


Something wrong with the way I'm doing it in Method 2. Please help me understand the way of doing heap allocation of 2-D array by passing pointers. Thanks.

Answer

On the first allocation you're not using the proper level of indirection. You want *ptr, not **ptr.

For the second and third allocations, operator precedence is getting you. The array index operator [] has higher precedence than the dereference operator * so you need parenthesis to first dereference, then index the array:

void test(char *** ptr)
{
    *ptr = calloc(2, sizeof(char *));
    (*ptr)[0] = malloc(256 * sizeof(char));
    (*ptr)[1] = malloc(256 * sizeof(char));
}

Rather than using a triple pointer (which as you found out can be confusing), return the allocated value instead and assign that to your variable:

char **test()
{
    char **ptr = calloc(2, sizeof(char *));
    ptr[0] = malloc(256 * sizeof(char));
    ptr[1] = malloc(256 * sizeof(char));
    return ptr;
}

...

arr = test();

Note that this is much cleaner.

Also, don't cast the return value of malloc/calloc/realloc.

Comments