简体   繁体   中英

Array of pointers initialization

 char **arr;
 arr = (char **)calloc(1,sizeof(char*));

 for(i = 0; i< 16; i++)
    if(arr[i] = (char *)calloc(1, 2*sizeof(char)) == NULL)
        perror("Memory cannot be allocated to arr[i]", %d);

The above code throws an error inside the for loop, when i am trying to allocate memory to arr[i]. Is anything wrong with this allocation. Essentially, i want to store 16 strings of length 2. I've tried it with array of pointers too (char *arr[16]). I have tried looking for resources on double pointer initializations using malloc() and calloc() and couldn't find many . If you could point out some links, that would be greatly appreciated. Thanks.

You need to allocate enough memory for 16 pointers, not just one.

arr = (char **)calloc(16, sizeof(char*));

What happens with your code is that arr has enough memory only for one pointer, so arr[0] = <something> is correct, but arr[1] and higher is touching memory that doesn't belong to the program.

Additionally, the way you assign the string pointers is wrong. You are assigning 0 or 1 values, depending on whether the result if calloc is NULL . You need to add parentheses there:

if ((arr[i] = (char *)calloc(1, 2*sizeof(char))) == NULL)
    perror("Memory cannot be allocated to arr[%d]", i);

Er even better:

for(i = 0; i < 16; i++) {
    arr[i] = (char *)calloc(1, 2*sizeof(char));
    if (arr[i] == NULL) {
        perror("Memory cannot be allocated to arr[%d]", i);
    }
}

When you use calloc , it is customary to use the first parameter to pass the number of elements in the array and the second parameter to pass the size of an element. So, to allocate an array of 16 pointers, one'd normally use calloc(16, <pointer size>) , not calloc(1, 16 * <pointer size>) , although both do the same thing. In your code you apparently completely forgot about 16 and allocated only 1 pointer.

Don't cast the result of 'calloc'.

Avoid using sizeof(<type>) when calculating size for memory allocation functions. Prefer to use sizeof *<pointer> instead.

If you want to store srings of length 2, you need a buffer of at least 3 characters long (an extra character for zero-terminator).

Memory allocation failure doesn't normally set errno , so perror is not an appropriate function to use here.

Yor assignment to arr[i] in if condition is missing braces. The operations are associated incorrectly. It won't compile as is.

char **arr; 
arr = calloc(16, sizeof *arr); 
for(i = 0; i < 16; i++)
    if((arr[i] = calloc(3, sizeof *arr[i]) == NULL)
        fprintf(stderr, "Memory cannot be allocated");

Finally, an unnamed "magic constant" (16 and 3) is most of the time not a good idea.

arr = (char **)calloc(1,sizeof(char*));

allocates one pointer to pointer to char.

Essentially, i want to store 16 strings of length 2

char **arr = calloc(16, sizeof *arr);

if (!arr) exit(-1); /* bail out somehow */

for(i = 0; i < 16; i++)
  if((arr[i] = calloc(2, sizeof *arr[ i ])) == NULL)
    printf("Memory cannot be allocated to arr[ %d ]", i + 1);

Check the parenthesization as well in your if condition and printf statement. Does your code even compile?

Storing two characters directly is less expensive than storing a pointer, so I'd suggest dropping one level of indirection and use a contigous block of memory:

char (*arr)[2] = calloc(16, sizeof *arr); 

Also keep in mind that your character sequences can't be strings as you didn't provide memory for the terminating 0 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM