Почему malloc работает, а calloc - нет, когда мы пытаемся использовать его для нескольких строк в C-программировании? - PullRequest
0 голосов
/ 23 мая 2018

В приведенном ниже коде я пытаюсь использовать двойной указатель для доступа к нескольким строкам, а также к каждому символу в каждой строке.Этот код ниже работает отлично, как ожидалось.Но мне интересно, почему это не работает, когда я удаляю операторы malloc, которые используются два раза, и вместо этого использую только один единственный оператор calloc, так как

ptr = (char **)calloc(2, sizeof(char)*20);

Вышеуказанный оператор Calloc делает то же самое, что делают два mallocзаявления в программе ниже.Функция Calloc просто инициализирует два массива каждого размера 20Bytes.Но все же я не понимаю, почему это не работает.

#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;
}

1 Ответ

0 голосов
/ 23 мая 2018

Выражение Calloc выше делает то же самое, что и два выражения malloc в программе ниже.

Нет, не будет.Если оставить в стороне тот факт, что ваш первый malloc() не выделяет достаточно места даже для одного указателя, а тем более двух, вы, похоже, не понимаете разницу между массивами и указателями.

Функция Calloc простоинициализировать два массива каждого размера 20 байт.Но все же я не понимаю, почему это не работает.

Это действительно разумный способ описать эффект этого вызова calloc() (когда он успешен).Более полное описание может состоять в том, что он выделяет и обнуляет пространство для массива из двух массивов по 20 char с.Но это не то же самое, что вы делаете со своими тремя malloc() вызовами в примере кода.

Вы ошибаетесь, когда назначаете результат вашего calloc() переменной указателятипа, который не соответствует.char ** - указатель на char *.Указатель на указатель может в некоторых случаях быть элементом массива таких указателей.Но массивы - это совсем не то же самое, что указатели, и, следовательно, массивы массивов - это не то же самое, что массивы указателей.

Вполне возможно, вы захотите этого, вместо этого:

char (*ptr)[20] = calloc(2 * sizeof(char) * 20);

или, лучше, это:

char (*ptr)[20] = calloc(2 * sizeof(*ptr));

В любом случае, ptr объявляется как указатель на массив из 20 char, и достаточно места зарезервировано для массива, на который указываетпервый элемент массива из двух таких.Полученный указатель можно использовать всеми способами, которые вы демонстрируете в своем вопросе, за исключением того, что вы должны free() только один указатель - других нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...