From 1cd34ef4a9289a122d10f9cb15076350599428d4 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Tue, 2 Sep 2025 17:59:51 -0400 Subject: [PATCH] Fix memory leak --- src/metric.cpp | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/src/metric.cpp b/src/metric.cpp index 1ba34f0..ab9728c 100644 --- a/src/metric.cpp +++ b/src/metric.cpp @@ -668,7 +668,7 @@ struct Metric { }; struct AggregateCounter { - std::vector thread_states; + std::span thread_states; Counter::State *global_state; }; @@ -677,7 +677,7 @@ struct Metric { }; struct AggregateHistogram { - std::vector thread_states; + std::span thread_states; Histogram::State *global_state; size_t bucket_count; std::span buckets; // For bucket threshold formatting @@ -724,26 +724,12 @@ struct Metric { new (&aggregate_histogram) AggregateHistogram(ah); } - // Destructor - ~RenderInstruction() { - switch (type) { - case InstructionType::CALL_COUNTER_CALLBACK: - counter_callback.~CallCounterCallback(); - break; - case InstructionType::CALL_GAUGE_CALLBACK: - gauge_callback.~CallGaugeCallback(); - break; - case InstructionType::AGGREGATE_COUNTER: - aggregate_counter.~AggregateCounter(); - break; - case InstructionType::AGGREGATE_GAUGE: - aggregate_gauge.~AggregateGauge(); - break; - case InstructionType::AGGREGATE_HISTOGRAM: - aggregate_histogram.~AggregateHistogram(); - break; - } - } + // Destructor not needed, all instructions are trivially destructible + static_assert(std::is_trivially_destructible_v); + static_assert(std::is_trivially_destructible_v); + static_assert(std::is_trivially_destructible_v); + static_assert(std::is_trivially_destructible_v); + static_assert(std::is_trivially_destructible_v); // Copy constructor and assignment RenderInstruction(const RenderInstruction &other) : type(other.type) { @@ -769,9 +755,8 @@ struct Metric { RenderInstruction &operator=(const RenderInstruction &other) { if (this != &other) { - // Destroy current object - this->~RenderInstruction(); - // Reconstruct with new type and data + // All union members are trivially destructible, so no need to call + // destructor. Just reconstruct with new type and data. type = other.type; switch (type) { case InstructionType::CALL_COUNTER_CALLBACK: