AppleGrew
AppleGrew

Reputation:

Creating pointer-to-pointer using malloc

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?

Upvotes: 1

Views: 663

Answers (7)

pmg
pmg

Reputation: 108938

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.

Upvotes: 1

sharptooth
sharptooth

Reputation: 170499

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).

Upvotes: 2

dave4420
dave4420

Reputation: 47052

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).

Upvotes: 1

Graeme Perrow
Graeme Perrow

Reputation: 57248

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.

Upvotes: 2

Drew Hall
Drew Hall

Reputation: 29055

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).

Upvotes: 1

Julien Lebosquain
Julien Lebosquain

Reputation: 41243

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.

Upvotes: 2

Mitch Wheat
Mitch Wheat

Reputation: 300559

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);

Upvotes: 9

Related Questions