From 8c5b419e7ad29753a5a52077bc93596ac65f3287 Mon Sep 17 00:00:00 2001 From: resserops Date: Tue, 4 Nov 2025 23:36:14 +0800 Subject: [PATCH] test(leetcode): introduce CRTP-based memory tracker to prevent memory leaks --- leetcode/CMakeLists.txt | 2 +- leetcode/list_node.hpp | 10 ++++++ leetcode/{test => }/test_utility.cpp | 0 leetcode/{test => }/test_utility.hpp | 0 leetcode/tracker.hpp | 53 ++++++++++++++++++++++++++++ 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 leetcode/list_node.hpp rename leetcode/{test => }/test_utility.cpp (100%) rename leetcode/{test => }/test_utility.hpp (100%) create mode 100644 leetcode/tracker.hpp diff --git a/leetcode/CMakeLists.txt b/leetcode/CMakeLists.txt index 6d9e7f4..cea1e39 100644 --- a/leetcode/CMakeLists.txt +++ b/leetcode/CMakeLists.txt @@ -1,7 +1,7 @@ # 构建测试对象库 file(GLOB_RECURSE TEST_SRC "*.cpp") add_library(test_leetcode_o OBJECT ${TEST_SRC}) -target_include_directories(test_leetcode_o PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test) +target_include_directories(test_leetcode_o PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/test) target_compile_definitions(test_leetcode_o PRIVATE PROBLEM_PATH=\"${CMAKE_CURRENT_SOURCE_DIR}\") target_compile_options(test_leetcode_o PRIVATE -Werror -Wall -Wextra -Wodr) diff --git a/leetcode/list_node.hpp b/leetcode/list_node.hpp new file mode 100644 index 0000000..e47c6b5 --- /dev/null +++ b/leetcode/list_node.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "tracker.hpp" + +struct ListNode : public Tracker { + int val; + ListNode *next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode *next) : val(x), next(next) {} +}; diff --git a/leetcode/test/test_utility.cpp b/leetcode/test_utility.cpp similarity index 100% rename from leetcode/test/test_utility.cpp rename to leetcode/test_utility.cpp diff --git a/leetcode/test/test_utility.hpp b/leetcode/test_utility.hpp similarity index 100% rename from leetcode/test/test_utility.hpp rename to leetcode/test_utility.hpp diff --git a/leetcode/tracker.hpp b/leetcode/tracker.hpp new file mode 100644 index 0000000..b5a5fec --- /dev/null +++ b/leetcode/tracker.hpp @@ -0,0 +1,53 @@ +#pragma once +#include +#include +#include +#include + +template +class Tracker { +public: + static void *operator new(std::size_t count) { + assert(count == sizeof(T)); + void *ptr{::operator new(count)}; + activeObjects_.insert(static_cast(ptr)); + return ptr; + } + + static void operator delete(void *ptr) { + assert(ptr != nullptr); + activeObjects_.erase(static_cast(ptr)); + ::operator delete(ptr); + } + + static void *operator new[](std::size_t count) { + assert(count % sizeof(T) == 0); + void *ptr{::operator new[](count)}; + activeArrays_.insert(static_cast(ptr)); + return ptr; + } + + static void operator delete[](void *ptr) { + assert(ptr != nullptr); + activeArrays_.erase(static_cast(ptr)); + ::operator delete(ptr); + } + + static void Clear() { + std::vector activeObjects(activeObjects_.begin(), activeObjects_.end()); + for (T *object : activeObjects) { + delete object; + } + std::vector activeArrays(activeArrays_.begin(), activeArrays_.end()); + for (T *array : activeArrays) { + delete[] array; + } + } + +protected: + Tracker() = default; + +private: + static inline std::unordered_set activeObjects_; + static inline std::unordered_set activeArrays_; +};