Должен ли я проверить, был ли malloc() успешным?



error-handling runtime-error (2)

Нет необходимости malloc() . Да, необходимо проверить, был ли malloc () успешным или нет. Предположим, что malloc() завершился неудачно, и вы пытаетесь получить доступ к указателю, думая, что память выделена, что приведет к сбою. Так что лучше поймать ошибку выделения памяти перед обращением к указателю.

int *arr = malloc(sizeof(*arr));
if(arr == NULL)
{
printf("Memory allocation failed");
return;
}

Следует ли после каждого malloc () проверять, был ли он успешным? Возможно ли, что malloc () завершится неудачно? Что происходит потом?

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

arr = (int) malloc(sizeof(int)*x*y);
if(arr==NULL){
    printf("Error. Allocation was unsuccessful. \n");
    return 1;
}

Какова практика в этом отношении? Могу ли я сделать это так:

if(!(arr = (int) malloc(sizeof(int)*x*y))
    <error>

Answer #1

Это в основном только добавляет к существующему ответу, но я понимаю, откуда вы пришли, если вы делаете много выделенного объема памяти, ваш код выглядит очень некрасиво со всеми проверками ошибок для malloc.

Лично я часто обхожу это, используя небольшую оболочку malloc, которая никогда не подведет. Если ваше программное обеспечение не является отказоустойчивой, критически важной для безопасности системой, вы все равно не сможете осмысленно обойти сбой malloc, поэтому я бы предложил нечто подобное

static inline void *MallocOrDie(size_t MemSize)
{
    void *AllocMem = malloc(MemSize);
    /* Some implementations return null on a 0 length alloc,
     * we may as well allow this as it increases compatibility
     * with very few side effects */
    if(!AllocMem && MemSize)
    {
        printf("Could not allocate memory!");
        exit(-1);
    }
    return AllocMem;
}

Который, по крайней мере, гарантирует, что вы получите сообщение об ошибке и чистый сбой, и позволит избежать всего объема кода проверки ошибок.

Для более общего решения для функций, которые могут потерпеть неудачу, я также стремлюсь реализовать простой макрос, такой как это:

#define PrintDie(...) \
    do \
    { \
    fprintf(stderr, __VA_ARGS__); \
    abort(); \
    } while(0)

Который затем позволяет запустить функцию как:

if(-1 == foo()) PrintDie("Oh no");

Который дает вам один вкладыш, снова избегая большого количества, включая надлежащие проверки.





allocation