realloc
возвращает NULL
, но не устанавливает errno
. Как правильно проверить наличие этой ошибки / нечетного поведения?
Для realloc()
, errno
не указано для установки по стандарту C. Любая настройка errno
является поведением, определяемым реализацией.
C действительно указывает:
Если размер запрошенного пространства равен нулю, поведение определяется реализацией: либо возвращается нулевой указатель, указывающий на ошибку, либо поведение такое, как если бы размер был некоторым ненулевым значением, за исключением того, что возвращенный указатель не должен использоваться для доступа к объекту. C17 / 18 § 7.22.3 1
Если размер равен нулю и память для нового объекта не выделена, определяется реализацией, был ли освобожден старый объект. C17 / 18 § 7.22.3.5 3
Попробуйте избежать 3 поведения, определяемого реализацией баллов. Используйте вспомогательную функцию и вызовите free()
, когда новый размер равен 0.
// Return error status
bool realloc_float(float **ptr, size_t new_size) {
// Size zero or too big ....
if (new_size == 0 || new_size > SIZE_MAX/sizeof(float)) {
free(*ptr);
*ptr = NULL;
return new_size > 0; // fail on large new_size
}
float *newp = realloc(*ptr, sizeof(float) * new_size);
if (newp == NULL) {
free(*ptr);
*ptr = NULL;
return true; // failure
}
*ptr = newp;
return false;
}
Использование
int main() {
float *ptr = NULL;
for (int i = 0; i < 10; i++) {
size_t sz = rand()%4;
bool err = realloc_float(&ptr, sz);
printf("Error: %d, Ptr value: %p, size %zu\n", err, (void*)ptr, sz);
}
free(ptr);
}