From 96eb8e8b0bcd192592d960647e402e953ee2f4d1 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Tue, 2 Sep 2025 15:25:38 -0400 Subject: [PATCH] Fix memory leaks --- src/metric.cpp | 51 +++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/metric.cpp b/src/metric.cpp index dca4af9..4b3fee0 100644 --- a/src/metric.cpp +++ b/src/metric.cpp @@ -329,19 +329,23 @@ struct Metric { // Global arena allocator for metric families and persistent global state static ArenaAllocator &get_global_arena() { - static ArenaAllocator global_arena(64 * 1024); // 64KB initial size - return global_arena; + static auto *global_arena = + new ArenaAllocator(64 * 1024); // 64KB initial size + return *global_arena; } // Function-local statics to avoid static initialization order fiasco static auto &get_counter_families() { - using FamilyMap = std::map< - std::string_view, Family::State *, std::less, - ArenaStlAllocator< - std::pair::State *>>>; - static FamilyMap *counterFamilies = new FamilyMap( - ArenaStlAllocator< - std::pair::State *>>( + using FamilyMap = + std::map::State>, + std::less, + ArenaStlAllocator< + std::pair::State>>>>; + static FamilyMap *counterFamilies = + new FamilyMap(ArenaStlAllocator< + std::pair::State>>>( &get_global_arena())); return *counterFamilies; } @@ -360,13 +364,16 @@ struct Metric { static auto &get_histogram_families() { using FamilyMap = - std::map::State *, + std::map::State>, std::less, - ArenaStlAllocator::State *>>>; - static FamilyMap *histogramFamilies = new FamilyMap( - ArenaStlAllocator< - std::pair::State *>>( + ArenaStlAllocator< + std::pair::State>>>>; + static FamilyMap *histogramFamilies = + new FamilyMap(ArenaStlAllocator< + std::pair::State>>>( &get_global_arena())); return *histogramFamilies; } @@ -872,11 +879,7 @@ Family create_counter(std::string_view name, std::string_view help) { auto name_view = arena_copy_string(name, global_arena); auto &familyPtr = Metric::get_counter_families()[name_view]; if (!familyPtr) { - // NOTE: Family::State instances are never destroyed - this is fine - // because the number of metric families is bounded by application design - familyPtr = new (global_arena.allocate_raw(sizeof(Family::State), - alignof(Family::State))) - Family::State(global_arena); + familyPtr = global_arena.construct::State>(global_arena); familyPtr->name = name_view; familyPtr->help = arena_copy_string(help, global_arena); } else { @@ -885,7 +888,7 @@ Family create_counter(std::string_view name, std::string_view help) { "metric family already registered with different help text", name); } Family family; - family.p = familyPtr; + family.p = familyPtr.get(); return family; } @@ -925,9 +928,7 @@ Family create_histogram(std::string_view name, std::string_view help, if (!family_ptr) { // NOTE: Family::State instances are never destroyed - this is fine // because the number of metric families is bounded by application design - family_ptr = new (global_arena.allocate_raw( - sizeof(Family::State), alignof(Family::State))) - Family::State(global_arena); + family_ptr = global_arena.construct::State>(global_arena); family_ptr->name = name_view; family_ptr->help = arena_copy_string(help, global_arena); @@ -971,7 +972,7 @@ Family create_histogram(std::string_view name, std::string_view help, name); } Family family; - family.p = family_ptr; + family.p = family_ptr.get(); return family; }