Использование calloc() и проверка на сбой в C

Добрый день!

Обычно, если бы я использовал malloc, я бы проверял сбой через:

int *A;

A=(int *)malloc(NUM_ELEMENTS*sizeof(int));
if (!A) {
    printf("mem failure, exiting \n");
    exit(EXIT_FAILURE);
}

Могу ли я сделать то же самое для calloc, даже если всем присвоено значение 0? Я нутром чувствую, что да, потому что мы будем проверять адрес памяти A, и не имеет значения, что A[0] равен 0, адрес памяти не будет нулевым, если он не сбой.


person James Adams    schedule 30.10.2014    source источник


Ответы (3)


Да, вы можете проверить ошибки calloc точно так же, как malloc. Однако, поскольку calloc довольно устойчив к ошибкам, вам обычно не нужно этого делать, как описано здесь как узнать, не удалось ли инициализировать calloc.

person phantom    schedule 30.10.2014
comment
@AggressiveSneeze. нет проблем дружище! Удачи! - person phantom; 30.10.2014
comment
Включение проверки может по-прежнему обнаруживать такие ошибки, как попытка выделить больше памяти, чем доступно. Меня поймали, запустив calloc(big_calculated_number) на 32-битной архитектуре; проверка того, удалось ли calloc, сэкономила бы мне день поиска ошибок! - person ms609; 18.05.2020

Да, ваше мышление верно. Вы можете сделать ту же проверку с calloc по указанным вами причинам.

person JS1    schedule 30.10.2014

Код ОП работает и с malloc(), и с calloc().

Но OP неверен: «адрес памяти не будет нулевым, если он не завершится ошибкой».

Если запрошенный размер выделения равен 0, возвращаемый указатель может быть NULL.

«Если размер запрошенного пространства равен нулю, поведение определяется реализацией: либо возвращается нулевой указатель, либо поведение такое, как если бы размер был некоторым ненулевым значением, за исключением того, что возвращенный указатель не должен использоваться для доступа к объект." C11dr §7.22.3.1 1

Более портативное решение:

A = calloc(NUM_ELEMENTS, sizeof *A);
A = malloc(NUM_ELEMENTS * sizeof *A);

// Add size check
if (!A && NUM_ELEMENTS != 0) {
   fputs("mem failure, exiting \n", stderr);
   exit(EXIT_FAILURE);
}

Конечно, если NUM_ELEMENTS всегда > 0, то эта дополнительная проверка не нужна.

person chux - Reinstate Monica    schedule 30.10.2014