Есть ли необходимость проверять NULL после выделения памяти, когда ядро ​​использует избыточную память - PullRequest
28 голосов
/ 12 февраля 2010

Обычная практика - проверять NULL (успешно ли выделена память) после malloc (), что-то вроде

void *ptr = malloc(10);    
if (ptr != NULL) {  
  // do some thing usefull  
} else {  
 // no memory. safely return/throw ...  
}  

с включенной в ядре перегрузкой памяти, есть ли шанс получить NULL? Должен ли я следовать практике религиозной проверки NULL для каждого распределения? Будет ли malloc возвращать NULL, несмотря на агрессивный механизм overcommit (я думаю, значение 1)?

На самом деле ядро ​​Android использует чрезмерную загрузку памяти (не уверен насчет значения, хотел бы знать его (значение избыточной передачи) и его значение). Некоторые исходные коды платформы (C / C ++) в Android (могут быть сторонними) не проверяют NULL и не перехватывают bad_alloc после выделения. Я что-то упустил?

В SO есть несколько потоков, касающихся переполнения памяти, но ни одна из них не разрешила мою путаницу.

РЕДАКТИРОВАТЬ: Если используется агрессивный overcommit NULL не будет возвращено (предположение 1). Если нет физической памяти и она пытается получить доступ к выделенной памяти (записать в выделенную память), OOM завершит работу некоторого процесса и выделит память для приложения, пока оно не будет уничтожено по очереди (предположение 2). В любом случае я не вижу необходимости проверять NULL (память выделяется или процесс уничтожается). я прав в своих предположениях?
Переносимость не имеет значения для этого вопроса.

Ответы [ 5 ]

38 голосов
/ 17 февраля 2010

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

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

8 голосов
/ 15 февраля 2010

Вы должны проверять возвращаемое значение на NULL каждый раз. Любая функция библиотеки может дать сбой. Даже fclose () делает (на отключенном общем ресурсе NFS, а ошибка fclose файла NFS означает, что данные не были сохранены).

Большая часть программного обеспечения написана плохо и не содержит всех проверок.

malloc не может вернуть что-либо кроме NULL или указателя. Все или ничего. Вы не можете получить 1 байт от malloc, если попросите 10.

2 голосов
/ 16 февраля 2010

Было бы желательно проверять NULL неукоснительно во всех вызовах функций, которые могут возвращать NULL, независимо от того, имеет ли ядро ​​избыточную память или нет.

В следующем фрагменте кода ниже показано, как проверить, работает ли вызов malloc или нет ...

void *ptr = malloc(10);
if (ptr != NULL){
   /* Do something here with ptr */
}else{
   /* Do something here if it fails */
}

Файловые операции, операции с памятью, но некоторые из них при неудаче будут возвращать NULL.

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

1 голос
/ 24 апреля 2018

хорошо ... в Linux, поскольку память не поддерживается страницей (изначально) и создает резервные копии страниц только после первого чтения / записи, ОС всегда удастся выделить вам память (если вы не исчерпали адресное пространство, что невозможно в 64-битные системы). Поэтому, если ему не хватает памяти и он не может дать вам обещанную память, OOM killer просто убьет ваше приложение или другое приложение, чтобы предоставить вам нужную страницу поддержки. Итак, независимо от того, выполняете ли вы проверку NULL или нет, результат один и тот же, сбой .......

0 голосов
/ 17 июля 2012

Нет, нет необходимости проверять результат malloc.

Задолго до сбоя malloc операционная система уже столкнулась со множеством проблем.

"OOM-Killer and overcommit" был бы лучшим выбором.

Что? Ваша операционная система не поддерживает "OOM-Killer and overcommit"?

Вот почему вы должны перейти на Linux (или Android)!

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