LINUX.ORG.RU

Почему надо проверять malloc на NULL

 , ,


1

3

Вообще выделение памяти проверять.

А вот потому что:

#include <stdio.h>
int main()
{
  unsigned char *a = NULL;
  int b = 0;
  unsigned long n = (unsigned long)&b;
 
  printf("b = %d, n = %lu\n",b,n);
  a[n]=1;
  printf("b = %d\n",b);
  return 0;
}

Запуск

$ gcc nullptr.c -o nullptr
$ ./nullptr 
b = 0, n = 140731726099148
b = 1

Запускалось в 64-битном (x86_64) Linux. Как видно, никаких сегфолтов и прочих ошибок. Конечно, адрес в районе 127 Тб в примере далеко за пределами доступного почти на всех компьютерах, но нет никаких гарантий, что на какой-то системе с каким-то компилятором и настройками среды значение не окажется более доступным. Могут быть и другие архитектуры (32-битные например), если запускать от root'а, то в начало может быть разрешена запись и там иметься память процесса. Или ещё какие-то варианты.

shdown, monk, liksys, Xenius - я думаю вам понравится. Пример сочинился по ходу чтения обсуждения Вышло издание 2,92 книги «Программирование: введение в профессию» А. В. Столярова (комментарий)

★★★★★

Последнее исправление: anonymous_incognito (всего исправлений: 1)
Ответ на: комментарий от bugfixer

Люди которые с пеной у рта кричат «конечно проверять!» ловко уходят от вопроса «а что собственно с этими ошибками делать?». И тут мы приходим к одному из двух сценариев:

если обработка сводится к разновидности abort() то почему она не делается централизовано?

В целом не самый плохой вариант. Почему не делается - вопрос к тем, кто пишет код. Если этот вариант устраивает - именно так и надо делать. Добавлять my_malloc и использовать его повсеместно. Только в библиотеках, пожалуйста, так не надо делать.

если обработка нетривиальна - а как оно вообще тестировалось?

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

При попытке «продать» мне вот это я бы требовал доказательств демонстрирующих что абсолютно каждый из этих «if»ов был hit во время тестирования.

Ахаха.

Было бы даже интересно посмотреть как народ выкрутиться пытался бы.

Ну если денежку готовы платить - #define MY_MALLOC(x) my_malloc(__FILE__, __LINE__, x) и лепите юнит-тесты, в которых my_malloc возвращает ошибку для заранее заготовленных file:line строк. По сути проблем-то в этом нет. Где только столько времени взять, чтобы такие тесты написать. Опять же может ИИ поможет? Он железный, не устаёт. Не знаю.

Но в целом это всё кажется довольно бессмысленным. Никто не обещает писать код без багов. Поэтому задавать вопросы, подразумевая данное - странновато. Опять же в C обработка ошибок обычно есть почти в каждой функции. И эта обработка ошибок в 99% случаев довольно однотипна - вернуть код ошибки вызывающему. В случае с malloc всё будет ровно так же. Вернуть код ошибки вызывающему, а он пускай думает, если хочет, или возвращает свой код ошибки (и в конце это всё кончается аналогично abort как и в первом предложении, но потенциально оставляется лазейка для альтернативных стратегий обработки ошибок.

vbr ★★★★★
()

https://godbolt.org/z/E1bK8faWz

щас попробую с дилетантского взгляда обьяснить, сама программа мейн и то, что будет в бинарнике, имеет абстрактное описание - оно представлено в таблице и то, что будет запускаться, соответствуя какому-то стандарту, который и внизу тоесть по ABI, диктуется стандартом абстрактным - это похоже на некое состояние сущности, которое может соприкасаясь на локальном компе с абстрактными интерфейсами взаимодействовать с реальным железом, получается эту абстрактную машину можно представить как-то, предположим абстрактная машина, которая не существует, но у ней ей код и есть методика её исполнения - абстрактная машина - код. Тогда получается у этой машины есть какие-то граничащие катализаторы, по-типо как безопасность, тоесть нельзя что-то делать потомучто это может нанести вред/порчу - это как бы ситуация неконтролируема, потомучто абстрактная машина дала сбой, по типо замыкания, и тогда нам придётся отлаживать нашу программу, чтобы понять где произошел сбой…

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

далее мы создали переменную! внимание мы её создали - это очень важно.

далее мы в n записали толи адрес той переменной, скорее всего адрес. но этот адрес СОЗДАН!, потомучто переменная создалась.

итак и самое интересное. * звёздочка даёт нам доступ к [] обращению всё верно, и тогда получается, когда мы забудем, что в этом гнезде пустота мы обращаемся к a[0] = 1; и https://godbolt.org/z/E1bK8faWz

anonymous
()
Ответ на: комментарий от safocl

даже UB в коде не может убедить грету тунберг танцевать лезгинку на берлине и если это предположение верно то ваше утверждение ошибочно

sni4ok
()
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария