Я согласен, что ошибка выделения памяти с помощью malloc редкая ситуация, и после такой ошибки, скорее всего, невозможно полноценное функционирование программы. Но меня удивляет, с каким упорством программисты, приводя эти аргументы, предлагают вообще ничего не делать в такой ситуации. Я не призываю всех делать сложные механизмы восстановления работы после нехватки памяти или использовать заранее выделенные резервные буферы. Многим программам не нужны такие сложные механизмы. Тем не менее я не понимаю, почему хотя бы минимально не обработать такие ситуации корректно. Раз других объяснений пока не хватило, попробую в этот раз рассказать короткую притчу.
Эта статья является расширенным комментарием для дискуссий на некоторых площадках. Поэтому если вы не в контексте, то предварительно отсылаю вас к этим двум публикациям:
- Четыре причины проверять, что вернула функция malloc
- Почему проверять результат вызова malloc c помощью assert плохая идея
Притча
Жила-была компания, занимающаяся разработкой программного обеспечения. Был у них большой клиент, который платил много денег и всё было хорошо. Но потом этот клиент начал жаловаться, что у некоторых пользователей приложения начали падать.
Почему падает вроде понятно — разыменование нулевого указателя. Понятно, да непонятно, так как разработчики не могут у себя проблему воспроизвести. Да ещё и клиент с приватными данными работает. Не пришлёт он тебе ни стектрейс, ни дамп, не позволит провести сеанс удалённой отладки.
Клиент же тем делом всё больше раздражается. Делать что-то надо. Отправляет компания разработчиков с исходниками и отладочными версиями в офис заказчика. Чтобы те баг искали под присмотром и в закрытом контуре.
Дорогое это удовольствие, так команду отвлекать, тем более что ехать нужно было в другую страну.
Нашли они баг. На некоторых 32-битных Windows машинах памяти мало было, или файл подкачки был маленький. Не хватало памяти иногда. Функция выделения памяти malloc возвращала NULL. Нулевой указатель разыменовывался, и программа падала.
Так почему было так сложно всё это сразу понять? А потому, что команда программистов ленивая была и не проверяла, что функция malloc возвращает. Думали, что раз памяти нет, то всё равно сделать ничего нельзя. Пусть программа падает. Она и падала с сообщением про нулевой указатель.
Программа как минимум могла бы напечатать "Out of memory". Это сократило бы время на исследование. Команду бы не пришлось никуда отправлять, а можно было бы быстро выяснить, что за характеристики и настройки у машин, на которых такое происходит. Да ещё бы и клиент более доволен был качеством программного обеспечения.
Вот такая история, которая то ли была, то ли нет. Пишу же я это из-за того, что есть программисты, которые продолжают оспаривать простые вещи. Ищут обоснования, почему не надо проверку писать, вместо того чтобы просто взять и написать код, адекватно реагирующий на различные ситуации.
Мораль
Не ленитесь. Обработайте указатель, который вернула функция malloc (realloc, calloc, strdup и т.д.). Да, проверка может не пригодиться на практике. Возможно, памяти всегда будет достаточно. Но что, вам жалко, что ли? Пишите надёжный код. Не будьте как те программисты из притчи.
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. Parable of null pointer for indolent C programmers.