tags:

views:

65

answers:

4

hi,

char **r;
r = (char **)malloc(10);

the above allocation is enough?dont i need allocate for char *r through for loop?any can explain which one is right?

+5  A: 

This is most certainly wrong. A char* is of a size that doesn't divide 10 on most architectures.

Here's some example code:

char** r;
// Allocate an array of 10 char* in r
r = (char**)malloc(10 * sizeof(*r));

Now each element of r is an allocated char* and can be used to point somewhere.

Note also that in the above code I cast (as you did) the result of malloc. This is necessary only if this code is compiled with a C++ compiler, not a C compiler which doesn't need the cast. OTOH, in C++ you would need new, not malloc.

Eli Bendersky
+1 for using sizeof *r
William Pursell
+5  A: 

Assuming you want to allocate 10 char pointers, this will not work. You are, instead, allocating memory for 10 bytes.

A char pointer is likely to be more than one byte. Hopefully, your compiler knows about the actual size of it.

char** r = (char**)malloc(sizeof (char*) * 10);

This allocates enough room for 10 char pointers. However, currently, they point nowhere useful. You need to allocate memory for them too:

int sizeOfMyStrings = 20;
for (int i = 0; i < 10; i++)
    r[i] = (char*)malloc(sizeoOfMyStrings);

This gives you 10 char pointers, each pointing to 20 bytes of allocated memory.

(There is no sizeof involved here because it would be sizeof(char), and sizeof(char) is defined to be 1.)

zneak
Small point: in C it's better not to cast the result of malloc (you have to do this in C++, but in C it's not needed and should be omitted so as not to mask otherwise helpful compiler warnings).
Paul R
Better style would be char **r = malloc(sizeof(*r) * 10 );
Nyan
A: 

A char **r is a pointer to a char pointer. It can be seen as an array of strings. If you wanted to initialise all of the memory for the array, you would need to do

r = (char **)malloc(sizeof(char *) * NUMBER_OF_ELEMENTS_OF_ARRAY);
for (i = 0; i < NUMBER_OF_ELEMENTS_OF_ARRAY; i++) {
    r[i] = (char *)malloc(sizeof(char) * LENGTH_YOU_WANT_STRING);
}

or something like that.

BobTurbo
A: 

A simple way to allocate memory for "2-dimensional" structure in a way that you want is:

#include <stdlib.h> /* for malloc() */

char **r;
/* we will allocate 'size' values, each of 'data_size' length */
size_t size = 10;
size_t data_size = 42;
size_t i;

/* allocate 'size' objects of the right type.
 *
 * Notes:
 *
 * 1. no casting the return value of malloc(),
 * 2. r = malloc(size * sizeof *r) is type-agnostic, so
      if you change the type of r, you don't need to remember
      to change the malloc() call */

r = malloc(size * sizeof *r);

/* Error check omitted for clarity.  In real code, always check for return
   value of malloc() */

for (i=0; i < size; ++i) {
    /* once again, no cast, and we use x = malloc(size * sizeof *x) idiom */
    r[i] = malloc(data_size * sizeof *r[i]);
}

The advantage of the above scheme is that it works with minimal effort for 3-, 4-, or higher dimensions, and is easier to read too.

In the above code, in the loop, I could have written malloc(data_size) instead of malloc(data_size * sizeof *r[i]), because sizeof(char) is guaranteed to be 1, but again, I prefer the above form because it's type-agnostic.

Alok