Reputation: 55
I don't understand clearly what happens when you cast allocated memory through double pointer, as:
char **ptr;
ptr=(char *)malloc(sizeof(char)*value);
for(i=0;i<value;i++)
ptr[i]=(char **)malloc(sizeof(char *)*another_value);
During the first call of malloc, a void * is casted to char * so, i can access it using *(ptr+i), but during the second call of malloc i don't understand why i need to cast void * to char **, would not be enough to cast it to char * ?
Upvotes: 0
Views: 1837
Reputation: 311048
It is a good idea to cast the void pointer returned by malloc to the type of the destination pointer. In this case you can find an error similar to the error in your code snippet.
char **ptr;
ptr=(char *)malloc(sizeof(char)*value);
Here variable ptr
has type char **
while the right side of the assignment statement has type char *
due to the casting. So the compiler shall issue an error (more precisely a diagnostic message) because there is no implicit conversion from char *
. to char **
By the way by this reason in C++ there is not allowed to assign a pointer of type void *
to pointers of other types because such a code is unsafe.
The other reason to cast the void pointer returned by malloc is to make your code self-documented. Consider for example the following statement
p = malloc( sizeof( *p ) );
Here it is difficult to understand what is the type of memory is allocated. It would be much better to write for example
p = ( double * )malloc( sizeof( *p ) );
In this case the statement is more clear and you need not to scroll a big program listing that to determine what is the type of p.
Take into account that a good program is a program where each statement provides you as much information as you need that to understand what the statement is trying to do and what types of variables envolved in expressions..
There is one more reason to cast the pointer returned by malloc. If you will try to compile your code with a C++ compiler then it will issue numerous errors for each using of malloc without casting. When you will transfer your code from C to C++ you will estimate the value of such casting.
Here is the correct using of malloc for your example
char **ptr;
ptr = ( char ** )malloc( value * sizeof( char * ) );
for ( i = 0; i < value; i++ )
ptr[i] = ( char * )malloc( another_value * sizeof( char ) );
Upvotes: -3
Reputation: 53016
The right way is
char **ptr;
ptr = malloc(sizeof(char *) * value); // value pointers of char
for(i=0;i<value;i++)
ptr[i] = malloc(sizeof(char)*another_value); // another_value of chars
your code compiled because void *
is automatically converted to any pointer type, but if you turn on warnings, the compiler would notify you that you are assigning pointers of incompatible types.
Without the casts however no warning will be issued.
Another thing, sizeof(char) != sizeof(char *)
you need value
pointers to char
and then each pointer will be pointing to another_value
array of char
s.
So the first call to malloc
you have to allocate value * sizeof(pointer)
, the syntax for that is
value * sizeof(char *)
/* ^ see the star here. */
and then you don't need sizeof(char)
since it's 1
, the following is correct
char **ptr;
ptr = malloc(sizeof(char *) * value); // value pointers of char
for(i=0;i<value;i++)
ptr[i] = malloc(another_value); // another_value of chars
Upvotes: 0
Reputation: 19874
You are doing it wrong.
First of all no need to cast malloc()
Please take a look at the changes below.
Since the return type of malloc()
is void *
no need to cast malloc()
char **ptr = (char **)malloc(sizeof(char *)*another_value);
for(i=0;i<value;i++)
ptr[i]=(char *)malloc(sizeof(char)*value);
Remove cast and have
char **ptr = malloc(sizeof(char *)*another_value);
for(i=0;i<value;i++)
ptr[i]= malloc(sizeof(char)*value);
Upvotes: 0
Reputation: 106082
Casting in the above snippet makes no sense. Do not cast return value of malloc
. And allocation is wrong too. It should be like:
ptr = malloc(sizeof(char*)*value);
and
ptr[i] = malloc(another_value);
Upvotes: 5
Reputation: 121397
Both are wrong.
Both casts are unnecessary as a void pointer (malloc
returns void*
) is compatible with any other data pointer.
See: http://c-faq.com/malloc/cast.html
Upvotes: 3