Fix Arena realloc bug
This commit is contained in:
@@ -77,32 +77,29 @@ void *ArenaAllocator::realloc_raw(void *ptr, uint32_t old_size,
|
|||||||
assert(current_block_ &&
|
assert(current_block_ &&
|
||||||
"realloc called with non-null ptr but no current block exists");
|
"realloc called with non-null ptr but no current block exists");
|
||||||
|
|
||||||
// Assert that offset is large enough (should always be true for
|
if (current_block_->offset >= old_size) {
|
||||||
// valid callers)
|
// Check if this was the last allocation by comparing with expected location
|
||||||
assert(current_block_->offset >= old_size &&
|
char *expected_last_alloc_start =
|
||||||
"offset must be >= old_size for valid last allocation");
|
current_block_->data() + current_block_->offset - old_size;
|
||||||
|
|
||||||
// Check if this was the last allocation by comparing with expected location
|
if (ptr == expected_last_alloc_start) {
|
||||||
char *expected_last_alloc_start =
|
// This is indeed the last allocation
|
||||||
current_block_->data() + current_block_->offset - old_size;
|
if (new_size > old_size) {
|
||||||
|
// Growing - check if we have space
|
||||||
|
size_t additional_space_needed = new_size - old_size;
|
||||||
|
|
||||||
if (ptr == expected_last_alloc_start) {
|
if (current_block_->offset + additional_space_needed <=
|
||||||
// This is indeed the last allocation
|
current_block_->size) {
|
||||||
if (new_size > old_size) {
|
// We can extend in place
|
||||||
// Growing - check if we have space
|
current_block_->offset += additional_space_needed;
|
||||||
size_t additional_space_needed = new_size - old_size;
|
return ptr;
|
||||||
|
}
|
||||||
if (current_block_->offset + additional_space_needed <=
|
} else {
|
||||||
current_block_->size) {
|
// Shrinking - just update the offset
|
||||||
// We can extend in place
|
size_t space_to_free = old_size - new_size;
|
||||||
current_block_->offset += additional_space_needed;
|
current_block_->offset -= space_to_free;
|
||||||
return ptr;
|
return new_size == 0 ? nullptr : ptr;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Shrinking - just update the offset
|
|
||||||
size_t space_to_free = old_size - new_size;
|
|
||||||
current_block_->offset -= space_to_free;
|
|
||||||
return new_size == 0 ? nullptr : ptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user