Подтвердить что ты не робот

Должны ли мы проверить, не удались ли выделения памяти?

Я видел много кода, который проверяет указатели NULL всякий раз, когда выполняется выделение. Это делает код многословным, и если он не выполняется последовательно, только когда программисту это кажется, он даже не гарантирует, что программа не выйдет из строя, когда закончится адресное пространство. Кроме того, если программа не может делать больше распределений, она не сможет выполнять свою функцию в любом случае, правильно?

Итак, мой вопрос: не лучше ли для большинства программ вообще не проверять и просто позволить программе сбой, если память закончится? По крайней мере, код более читабельен таким образом.

Примечание

Я говорю о настольных приложениях, которые работают на современных компьютерах (не менее 2 ГБ адресного пространства), и которые, безусловно, не используют космические челноки, системы жизнеобеспечения или нефтяные платформы BP. Самое главное, что я говорю о программах, использующих malloc, но никогда не превышающих 5 МБ использования памяти.

4b9b3361

Ответ 1

Всегда проверяйте возвращаемое значение, но для ясности он обычно обертывает malloc() в функции, которая никогда не возвращает NULL:

void *
emalloc(size_t amt){
    void *v = malloc(amt);  
    if(!v){
        fprintf(stderr, "out of mem\n");
        exit(EXIT_FAILURE);
    }
    return v;
}

Затем, позже вы можете использовать

char *foo = emalloc(56);
foo[12] = 'A';

Без вины совести.

Ответ 2

Да, вы должны проверить нулевое возвращаемое значение из malloc. Даже если вы не можете восстановиться после сбоя в распределении памяти, вы должны явно выйти. Выполнение так, как будто выделение памяти преуспело, оставляет ваше приложение в противоречивом состоянии и, вероятно, вызывает "поведение undefined", которого следует избегать.

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

Многие приложения, которые хотят выйти из обрыва сложения malloc, в функции, которая проверяет возвращаемое значение и явно прерывает сбой.

Возможно, это одно из преимуществ подхода С++ по умолчанию new для исключения исключения при сбое распределения. Это не требует усилий для выхода из отказа памяти.

Ответ 3

Подобно подходу Dave выше, но добавляет макрос, который автоматически проходит имя файла и номер строки в нашу процедуру распределения, чтобы мы могли сообщать эта информация в случае сбоя.

#include <stdio.h>
#include <stdlib.h>

#define ZMALLOC(theSize) zmalloc(__FILE__, __LINE__, theSize)

static void *zmalloc(const char *file, int line, int size)
{
   void *ptr = malloc(size);

   if(!ptr)
   {
      printf("Could not allocate: %d bytes (%s:%d)\n", size, file, line);
      exit(1);
   }

   return(ptr);
}

int main()
{
   /* -- Set 'forceFailure' to a non-zero value in order to observe
         how 'zmalloc' behaves when it cannot allocate the
         requested memory -- */

   int bytes        = 10 * sizeof(int);
   int forceFailure = 0;
   int *anArray     = NULL;

   if(forceFailure)
      bytes = -1;

   anArray = ZMALLOC(bytes);

   free(anArray);

   return(0);
}

Ответ 4

но гораздо сложнее устранить неполадки, если вы не регистрируетесь, где сбой malloc.

не удалось выделить память в строке XX, чтобы предпочесть, чем просто сбой.

Ответ 6

В размещенной среде ошибка проверки возврата malloc в настоящее время не имеет большого значения. Большинство машин имеют виртуальное адресное пространство 64 бит. Тебе понадобится много времени, чтобы исчерпать это. Ваша программа, скорее всего, потерпит неудачу в совершенно другом месте, а именно, когда ваша физическая + своп-память исчерпана. До этого она показала совершенно нелепую работу, потому что она была только заменой, и пользователь запустил Cntrl-C задолго до того, как вы когда-нибудь придете туда.

Segfaulting "красиво" в ссылке на нулевой указатель будет четким моментом, чтобы увидеть, что в отладчике происходит ошибка. Но в моей практике я никогда не видел неудавшегося malloc в качестве причины.

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

Изменить: Чтобы уточнить, что после редактирования вопроса. Тип программ/систем, описанных там, явно не "внедрен". Я никогда не видел, чтобы malloc терпел неудачу в описанных там обстоятельствах.

Ответ 7

Я хотел бы добавить, что кромки всегда должны быть проверены, даже если вы считаете, что они безопасны или не могут привести к другим проблемам, чем к сбою. Возможно, существует возможность разыменования нулевых указателей (http://uninformed.org/?v=4&a=5&t=sumry).