Reputation: 65
In below code I am trying to use double pointer to access multiple strings as well as each character in every string. This below code is working perfectly as expected. But I wonder why it doesn't work when I remove the malloc statements which are used two times and instead use only one single calloc statement as
ptr = (char **)calloc(2, sizeof(char)*20);
Calloc statement above does same thing which is done by two malloc statements in below program. Calloc function will simply initialize two arrays of each size 20Bytes. But still I don't understand why this doesn't work.
#include <stdio.h>
#include <stdlib.h>
int main(){
int i=0;
char **ptr=NULL;
ptr =(char **) malloc(2*sizeof(char));
if(ptr==NULL){
printf("Memory not allocated!\n");
return -1;
}
for(i=0; i<2;i++){
ptr[i] = (char *)malloc(20*sizeof(char));
if(ptr[i]==NULL){
printf("Memory not allocated!\n");
return -1;
}
}
for(i=0; i<2;i++)
scanf("%s", ptr[i]);
for(i=0; i<2; i++)
printf("%s\n", ptr[i]);
for(i=0; i<4; i++)
printf("%c\n", ptr[0][i]);
for(i=0; i<4; i++)
printf("%c\n", ptr[1][i]);
free(ptr[0]);
free(ptr[1]);
free(ptr);
return 0;
}
Upvotes: 0
Views: 611
Reputation: 180998
Calloc statement above does same thing which is done by two malloc statements in below program.
No, it will not. Setting aside the fact that your first malloc()
does not allocate enough space even for one pointer, much less two, you seem to be confused about the difference between arrays and pointers.
Calloc function will simply initialize two arrays of each size 20Bytes. But still I don't understand why this doesn't work.
That's indeed a reasonable way to describe the effect of that calloc()
call (when it succeeds). A more complete description might be that it allocates and zeroes space for an array of two arrays of 20 char
s. But that is not the same thing you do with your three malloc()
calls in the example code.
You go wrong when you assign the result of your calloc()
to a pointer variable of a type that doesn't match. char **
is a pointer to a char *
. The pointed-to pointer might in some cases be an element of an array of such pointers. But arrays are not at all the same thing as pointers, and thus arrays of arrays are not the same thing as arrays of pointers.
Quite possibly you want this, instead:
char (*ptr)[20] = calloc(2 * sizeof(char) * 20);
or, better, this:
char (*ptr)[20] = calloc(2 * sizeof(*ptr));
In either case, ptr
is declared as a pointer to an array of 20 char
, and sufficient space is reserved for the pointed-to array to be the first element of an array of two such. You can use the resulting pointer in all the ways you demonstrate doing in your question, except that you must free()
only the one pointer -- there aren't any others.
Upvotes: 2