Стандарт C99 §7.20.3.4 (realloc) гласит:
Функция realloc освобождает старый объект, на который указывает ptr, и возвращает
указатель на новый объект, размер которого указан по размеру. Содержание нового
объект должен быть таким же, как и у старого объекта до освобождения, до
новые и старые размеры. Любые байты в новом объекте, превышающие размер старого объекта, имеют
неопределенные значения.
Если ptr является нулевым указателем, функция realloc ведет себя как функция malloc для
указанный размер. В противном случае, если ptr не совпадает с указателем, ранее возвращенным
функции calloc, malloc или realloc, или если пространство было освобождено вызовом
для функции free или realloc поведение не определено. Если память для нового
объект не может быть размещен, старый объект не освобожден и его значение не изменилось.
Возвращает
Функция realloc возвращает указатель на новый объект (который может иметь тот же
значение как указатель на старый объект), или нулевой указатель, если новый объект не может быть
выделено. * * 1 010
Обратите внимание, что старый объект освобожден; новый объект может оказаться в том же месте, что и старый. И могут быть проблемы. Это довольно маловероятно, но гораздо проще следовать правилу «всегда», чем иметь странные исключения.
Обычный контраргумент: «если это не может не получиться, значит, у меня есть путь ошибки, который я не могу проверить». До определенного момента, это правда. Тем не менее, может случиться так, что произошла некоторая утечка памяти, так что распределение не может быть успешным - потому что управляющая информация была повреждена. Скорее всего, вы просто получите дамп ядра, но, возможно, код достаточно надежен, чтобы этого избежать. (Я предполагаю, что жестко закодированные 100 и 50 предназначены для постановки вопроса; реальный код не будет перераспределять, когда знает, сколько ему действительно нужно.)
Там, где два вызова функции realloc () смежны, как здесь, очень мало места для того, чтобы что-то пошло не так. Однако в реальном рабочем коде между этими двумя операциями должно быть несколько операций, и этот код может вызвать сбой второго метода realloc ().
Относительно вашего «Правка 2» ...
Код может быть лучше написан как:
if (b != NULL)
a = b;
return a;
Но основная концепция в порядке. Обратите внимание, что в стандарте прямо сказано, что исходное распределение безопасно, если новое не может быть создано.