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