C - Malloc или calloc ... и как? - PullRequest
       32

C - Malloc или calloc ... и как?

2 голосов
/ 30 апреля 2010

У меня есть текстовый файл, где первое число определяет размер массивов. Я знаю, что calloc или malloc может зарезервировать память, но как?

этот код:

typedef struct alpha {
    int* size;
    char name;
    int  tot;
    char line[60];
} ALPHA;

fgets(line, 60, fp);
tot = atoi(line);
size = (int*)calloc(name, sizeof(int);

Представьте, что в первой строке текста стоит число 10, с этим кодом размер имени будет 10? как имя [10] ???

Ответы [ 4 ]

3 голосов
/ 30 апреля 2010

Есть несколько проблем с вашим кодом.

Во-первых, вы, кажется, путаете объявление типа данных с фактической переменной. Вы объявляете struct, и с тех пор это тип данных, очень похожий на int или double. Прежде чем назначить что-либо одному, вам нужно его иметь. Вы можете получить его, определив его в функции (ALPHA a;) или выделив память для одного с помощью malloc() или calloc().

Чтобы использовать calloc(), у вас есть два аргумента: один - сколько вам нужно, а другой - размер чего угодно. Для malloc() вы умножаете два. Другое отличие состоит в том, что malloc() возвращает память с тем, что было в ней, в то время как calloc() инициализирует все до нуля. (Это строка нулевой длины или целые нули в соответствии со Стандартом. Другие значения не гарантируются, но в большинстве современных систем вы получите эквивалент ноля.) Эти функции возвращают указатель на выделенную память.

Кажется, вам нужны tot int s, поэтому (используя calloc()) правильное утверждение будет выглядеть примерно так: int * a = calloc(tot, sizeof(int)); или int * a = calloc(tot, sizeof(*a)); В C не требуется приведение (это требуется в C ++, но вы обычно не используете malloc() или calloc() в C ++), и единственное, что он может сделать, это скрыть возможную ошибку (исключив #include <stdlib.h>) чтобы быть конкретным).

Получив это, вы можете ссылаться на int как что-то вроде a[3].

Поместить результат в поле ALPHA выполнимо, но вам действительно нужен ALPHA, так что-то вроде

ALPHA a;
a.size = calloc(tot, sizeof(*a));

будет работать. Поэтому вы бы назвали его, например, a.size[3].

Кроме того, я не вижу, что делает name. Это один символ, которого недостаточно для любой непустой строки, и я не знаю, почему вы получили его в вызове calloc(). Возможно, вы захотите, чтобы name была динамически размещаемой строкой с размером size. В этом случае вам нужно изменить строки в объявлении ALPHA на

int size;
char * name;

и код может быть

ALPHA a;
fgets(line, 60, fp);
a.size = atoi(line);
a.name = calloc(a.size, sizeof(*a.name));

Как только вы это сделаете, после ввода 10 вы можете обратиться к a.name[0] - a.name[9], и это ваши десять символов. a.name[10] будет один за концом. Обратите внимание, что в массив из десяти символов можно поместить только строку из девяти символов, поскольку вам нужно иметь место для нулевого терминатора ('\0', который является последним символом любой строки в стиле C). Если вы хотите иметь возможность ввести указанное количество символов, вам нужно добавить 1 к a.size после ввода введенного пользователем номера.

3 голосов
/ 30 апреля 2010

Используйте одно из следующего:

ALPHA* alphas1 = calloc(tot, sizeof(ALPHA));
// or
ALPHA* alphas2 = malloc(tot * sizeof(ALPHA));

Они выделяют память для tot ваших ALPHA структур.

1 голос
/ 30 апреля 2010

Вы можете просто захотеть

ALPHA alphas [tot];

0 голосов
/ 30 апреля 2010
ALPHA *alphas1 = calloc(tot, sizeof(*alphas1));
ALPHA *alphas2 = malloc(tot * sizeof(*alphas2));

- немного лучшая версия:

ALPHA* alphas1 = calloc(tot, sizeof(ALPHA));
ALPHA* alphas2 = malloc(tot * sizeof(ALPHA));

Теперь вы можете получить доступ к alphas1 и т. Д. "Как в массиве":

alphas1[0], alphas1[1], alphas1[2], ..., alphas1[tot] 
alphas2[0], alphas2[1], alphas2[2], ..., alphas2[tot] 

alphas1[...] относится к типу ALPHA
alphas2[...] имеет тип ALPHA.

PS: Чтобы сделать ваш код более надежным, не забудьте проверить, не удалось ли malloc / calloc. Для этого убедитесь, что (в вашем случае) проверьте, отличаются ли alphas1 или alphas2 от NULL. В случае, если они NULL, вы не сможете получить к ним доступ в том виде, в котором они представлены, и вам следует разработать механизм для восстановления после этого или просто выйти из программы (+ сообщение об ошибке).

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