Don't traverse to count; fix memory leak in reset

This commit is contained in:
2025-08-14 11:57:17 -04:00
parent 34cd98e83e
commit e1c47881a6
2 changed files with 97 additions and 66 deletions

View File

@@ -6,17 +6,17 @@
TEST_CASE("ArenaAllocator basic construction") {
ArenaAllocator arena;
CHECK(arena.num_blocks() == 1);
CHECK(arena.num_blocks() == 0);
CHECK(arena.used_bytes() == 0);
CHECK(arena.total_allocated() == 1024);
CHECK(arena.available_in_current_block() == 1024);
CHECK(arena.total_allocated() == 0);
CHECK(arena.available_in_current_block() == 0);
}
TEST_CASE("ArenaAllocator custom initial size") {
ArenaAllocator arena(2048);
CHECK(arena.num_blocks() == 1);
CHECK(arena.total_allocated() == 2048);
CHECK(arena.available_in_current_block() == 2048);
CHECK(arena.num_blocks() == 0);
CHECK(arena.total_allocated() == 0);
CHECK(arena.available_in_current_block() == 0);
}
TEST_CASE("ArenaAllocator basic allocation") {
@@ -93,7 +93,7 @@ TEST_CASE("ArenaAllocator block management") {
SUBCASE("allocation larger than block size grows arena") {
void *ptr = arena.allocate(200);
CHECK(ptr != nullptr);
CHECK(arena.num_blocks() == 2);
CHECK(arena.num_blocks() == 1);
}
}
@@ -146,12 +146,43 @@ TEST_CASE("ArenaAllocator reset functionality") {
CHECK(arena.used_bytes() == 50);
}
TEST_CASE("ArenaAllocator reset memory leak test") {
ArenaAllocator arena(32); // Smaller initial size
// Force multiple blocks
arena.allocate(30); // First block (32 bytes)
CHECK(arena.num_blocks() == 1);
arena.allocate(30); // Should create second block (64 bytes due to doubling)
CHECK(arena.num_blocks() == 2);
arena.allocate(100); // Should create third block (128 bytes due to doubling,
// or larger for 100)
CHECK(arena.num_blocks() == 3);
size_t total_before = arena.total_allocated();
CHECK(total_before > 32);
arena.reset();
// After reset, only first block should remain (others freed to prevent memory
// leak)
CHECK(arena.num_blocks() == 1);
CHECK(arena.total_allocated() == 32); // Only first block size
CHECK(arena.used_bytes() == 0);
// Should be able to use the first block again
void *ptr = arena.allocate(20);
CHECK(ptr != nullptr);
CHECK(arena.used_bytes() == 20);
}
TEST_CASE("ArenaAllocator memory tracking") {
ArenaAllocator arena(512);
CHECK(arena.total_allocated() == 512);
CHECK(arena.total_allocated() == 0);
CHECK(arena.used_bytes() == 0);
CHECK(arena.available_in_current_block() == 512);
CHECK(arena.available_in_current_block() == 0);
arena.allocate(100);
CHECK(arena.used_bytes() >= 100);