Return a small allocation from realloc(ptr, 0). (#460)
An annoying amount of real-world code (e.g. mandoc, BSD sort) treats a NULL return from `realloc` as a failure, even when requesting a size of 0. This code is wrong (the standard explicitly permits a return of NULL from realloc when given a size 0) but working around it in snmalloc is easier than fixing it everywhere.
This commit is contained in:
@@ -480,9 +480,14 @@ namespace snmalloc
|
||||
{
|
||||
return bits::next_pow2(size);
|
||||
}
|
||||
// If realloc(ptr, 0) returns nullptr, some consumers treat this as a
|
||||
// reallocation failure and abort. To avoid this, we round up the size of
|
||||
// requested allocations to the smallest size class. This can be changed
|
||||
// on any platform that's happy to return nullptr from realloc(ptr,0) and
|
||||
// should eventually become a configuration option.
|
||||
if (size == 0)
|
||||
{
|
||||
return 0;
|
||||
return sizeclass_to_size(size_to_sizeclass(1));
|
||||
}
|
||||
return sizeclass_to_size(size_to_sizeclass(size));
|
||||
}
|
||||
|
||||
@@ -36,12 +36,19 @@ void check_result(size_t size, size_t align, void* p, int err, bool null)
|
||||
failed = true;
|
||||
}
|
||||
const auto alloc_size = our_malloc_usable_size(p);
|
||||
const auto expected_size = round_size(size);
|
||||
auto expected_size = round_size(size);
|
||||
#ifdef SNMALLOC_PASS_THROUGH
|
||||
// Calling system allocator may allocate a larger block than
|
||||
// snmalloc. Note, we have called the system allocator with
|
||||
// the size snmalloc would allocate, so it won't be smaller.
|
||||
const auto exact_size = false;
|
||||
// We allocate MIN_ALLOC_SIZE byte for 0-sized allocations (and so round_size
|
||||
// will tell us that the minimum size is MIN_ALLOC_SIZE), but the system
|
||||
// allocator may return a 0-sized allocation.
|
||||
if (size == 0)
|
||||
{
|
||||
expected_size = 0;
|
||||
}
|
||||
#else
|
||||
const auto exact_size = align == 1;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user