tags:

views:

157

answers:

7

The code is

char** p = (char **) malloc(sizeof(char **) * size); //Where size is some valid value.
p[1] = (char*) malloc(sizeof(char) * 30);

Is the above code fine?

My understanding is

p -> +---------+
     0 char*   + -> {c,o,d,e,\0}
     +---------+

     +---------+
     1 char*   + -> {t,o,a,d,\0} //The assignment of these values is not shown in the code.
     +---------+

So we should instead write

char** p = (char **) malloc(sizeof(char *) * size);

Am I correct?

And is p[0] means *(p + 1) where p+1 will point to "toad" so "toad" will be returned?

+8  A: 

As a general rule, the '*-ness' of the thing you take the size of inside the malloc call should be 1 '*' less than the pointer receiving the malloc'ed memory.

for instance:

char * p = malloc(sizeof(char) * somesize);

and

char ** p = malloc(sizeof(char *) * somesize);
Mitch Wheat
+1, not only for the word "asteriskness" :)
avakar
+2  A: 

Yes, you should malloc() sizeof(char*) since you intend to store char* in the array.

In most cases sizeof(char **) will be equal to sizeof(char *) so the initial code will work too but you really shouldn't rely on this - it's not absolutely portable and such code is confusing.

p[0] means *(p + 0), not (*p + 1). p[1] would mean *(p + 1).

sharptooth
+2  A: 

Yes, you're basically allocating an array of char* here, of size size. sizeof(char *) should indeed be used instead of sizeof(char **), but it won't change anything in practice since a pointer is always the same size.

p[0] means *p, I assume you meant p[1] means *(p + 1), which is correct.

Julien Lebosquain
Sorry my bad. I meant to write p[1] but wrote p[0].
AppleGrew
+1  A: 

You're correct. It should be

char** p = (char**) malloc(sizeof(char*) * size);

As for your last question, I don't quite follow. p[0] means *(p+0). p[1] means *(p+1).

Drew Hall
+2  A: 

Yes and no. You are correct that the first allocation should use sizeof( char * ) but since pointers and pointers to pointers have the same size, it won't matter.

But p[0] points to the buffer holding "code" while p[1] points to the buffer holding "toad". The code is allocating an array of pointers and then filling in the second element of the array while leaving the first uninitialized.

Graeme Perrow
+1  A: 

Yes, you should write

char** p = (char **) malloc(sizeof(char *) * size);

But no, p[0] means *(p + 0) where p+0 will point to "code" so "code" will be returned.

If you want "toad", use p[1], which means *(p + 1).

Dave Hinton
A: 

I always do it like this:

#include <stdlib.h>
pointer = malloc(ELEMENTS * sizeof *pointer);
/* check if pointer is NULL */

In your case that becomes:

#include <stdlib.h>
char** p = malloc(sizeof *p * size); //Where size is some valid value.
/* check if p is NULL */
p[1] = malloc(sizeof *(p[1]) * 30);
/* check if p[1] is NULL */

Note: In C, the return value of malloc should not be cast! void * is perfectly acceptable to assign to any other pointer type. In C++ it might be different.

pmg