using array of chars and strdup, getting segmentation fault

340 Views Asked by At

Suppose i write,

char **p;
p[0] = strdup("hello");

Strdup creates a duplicate string in heap with ending character '\0'; As p is pointer to pointer of char, p[0] = strdup("hello") seems perfectly fine for me. But why am i getting segmentation fault.

2

There are 2 best solutions below

0
Steve Summit On

Let's look at a simpler example. Suppose you say

int *ip;
ip[0] = 5;

ip is a pointer to one or more ints -- but it's not initialized, so it points nowhere, so ip[0] isn't a valid memory location, so we can't store the value 5 there.

In the same way, when you said

char **p;

p is a pointer that points nowhere. If it did point somewhere, it would point to another pointer. But it doesn't point anywhere, so

p[0] = strdup("hello");

blows up.

To fix this, you need to make p point somewhere, and specifically to memory allocated to hold one or more pointers. There are many ways to do this:

char *q;
p = &q;                                 /* way 1 */

char *a[10];
p = a;                                  /* way 2 */

p = malloc(10 * sizeof(char *));        /* way 3 */

or instead of using a pointer, use an array to start with:

char *p[10];                            /* way 4 */

After any of those, p[0] = strdup("hello") should work.

For way 3, we would also need to check that malloc succeeded (that it dd not return a null pointer).

For ways 2 through 4, we could also set p[1] through p[9]. But for way 1, only p[0] is valid.

See also this answer to a different question for more discussion about trying to use uninitialized pointers.

0
Vlad from Moscow On

There is declared an uninitialized pointer that has an indeterminate value.

char **p;

so dereferencing the pointer in this expression p[0] (that is equivalent to the expression *p) used in this statement

p[0] = strdup("hello");

invokes undefined behavior because there is an attempt to write to memory using an incorrect pointer value of the expression p[0].

You could write either for example

char *s;
char **p = &s;
p[0] = strdup("hello");

Or

char **p = malloc( sizeof( char * ) );
p[0] = strdup("hello");

That is the pointer to pointer p must point to a valid object. Thus dereferencing the pointer you will get a valid object of the type char * that will be assigned by the value returned by the call of strdup..