Память в программе выделяется при помощи оператора NEW, а вот что делать дальше, там возможны вариации:
1) Можно сразу начать использовать выделенную память. В случае, если памяти не хватило, и выделенная переменная была NIL, программа сразу же упадёт.
2) Можно проверить, что выделенная переменная не NIL. В случае, если она не NIL, то продолжить работу, возможно, дальше выделять еще динамические объекты, в случае же если NIL, то как можно быстрее закончить работу функции и вернуть результат работы функции, как FALSE.
Бывают ситуации, когда несколько динамических объектов взаимодействуют друг с другом, допустим, есть динамическая строка, где содержится многострочный текст, и динамический массив позиций начала каждой строки. Может быть такая ситуация, что сначала текст добавляется в динамическую строку, а затем вычисляются позиции начала каждой строки, но на этом этапе может возникнуть ситуация, что памяти может не хватить. И может получится так, что динамическая строка увеличивалась, а динамический массив позиций начала строк не увеличился. И система будет находится в несогласованном состоянии.
3) Можно реализовать у каждого динамического объекта функцию Revert, которая будет отменять последнюю выполненную операцию добавления данных. И в случае, если динамическая строка выделилась, а массив динамических строк не выделился, то вызвать операцию Revert для динамической строки и вернуть результат работы функции, как FALSE. В этом случае, если результат работы функции FALSE, то это будет означать, что ничего не добавилось и все данные остались в том же состоянии, что и до попытки добавить данные.

Как мне кажется, третий вариант наиболее продвинутый, но не будет ли такая реализация излишним усложнением? Кто какие подходы использует?

И как можно тестировать ошибки выделения памяти? Допустим, можно написать обёртку над NEW и, например, искусственно возвращать NIL, это можно легко сделать, если хочется всегда возвращать NIL. А вот как сделать так, чтобы память успешно выделялась на этапе выделения динамической строки, но возвращала NIL, на этапе выделения динамического массива с позициями начала каждой строки? Конечно, зная реализацию, можно подсчитать, что N-ый NEW должен вернуть NIL и завести счетчик внутри обертки, который будет считать сколько NEW было вызвано. Но в данном случае, такой тест становится очень чувствительным к любым изменениям в реализации. Допустим, если добавится, еще какой-нибудь вызов функции, который выделяет память, то все подсчеты могут съехать. Можно ли сделать такой тест более надежным?