From e76a8ce1b769de7ea43cb9d77c9613979fd47e72 Mon Sep 17 00:00:00 2001 From: amass <168062547@qq.com> Date: Mon, 16 Sep 2024 01:32:40 +0800 Subject: [PATCH] fix mem leak. --- CMakeLists.txt | 1 + DataStructure/KylinString.cpp | 123 ++++++++++++++++------ UnitTest/DataStructure/BinaryTreeTest.cpp | 76 ++++++++++--- UnitTest/Universal/DateTimeTest.cpp | 7 +- Universal/CMakeLists.txt | 6 ++ Universal/MessageManager.cpp | 4 + Universal/MessageManager.inl | 4 + 7 files changed, 170 insertions(+), 51 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41878aa..f6ff129 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.15) project(Kylin) option(INDEPENDENT_BUILD "build self." OFF) +option(DISABLE_LOG "disable log" OFF) option(UNIT_TEST "do unit test" OFF) if(INDEPENDENT_BUILD) diff --git a/DataStructure/KylinString.cpp b/DataStructure/KylinString.cpp index f628e41..eb8a5e1 100644 --- a/DataStructure/KylinString.cpp +++ b/DataStructure/KylinString.cpp @@ -4,16 +4,22 @@ namespace Kylin { -String::String() { init(nullptr); } +String::String() { + init(nullptr); +} String::String(const char c) { char str[] = {c, '\0'}; init(str); } -String::String(const char *str) { init(str); } +String::String(const char *str) { + init(str); +} -String::String(const String &str) { init(str.m_str); } +String::String(const String &str) { + init(str.m_str); +} String::String(String &&other) { m_str = other.m_str; @@ -21,9 +27,13 @@ String::String(String &&other) { other.init(nullptr); } -String::~String() { delete m_str; } +String::~String() { + free(m_str); +} -String &String::operator=(const String &str) { return operator=(str.m_str); } +String &String::operator=(const String &str) { + return operator=(str.m_str); +} String &String::operator=(const char *str) { if (m_str != str) { @@ -46,7 +56,9 @@ bool String::startWith(const char *s) const { return true; } -bool String::startWith(const String &s) const { return startWith(s.m_str); } +bool String::startWith(const String &s) const { + return startWith(s.m_str); +} bool String::endOf(const char *s) const { if (s == nullptr) return false; @@ -59,15 +71,16 @@ bool String::endOf(const char *s) const { return true; } -bool String::endOf(const String &s) const { return endOf(s.str()); } +bool String::endOf(const String &s) const { + return endOf(s.str()); +} String &String::insert(size_t index, const char *s) { if (s != nullptr) { if (index > m_length) THROW_EXCEPTION(InvalidParameterException, "Index i is a invalid parameter..."); auto size = strlen(s); auto str = reinterpret_cast(malloc(m_length + size + 1)); - if (str == nullptr) - THROW_EXCEPTION(NoEnoughMemoryException, "There is no memory to create string..."); + if (str == nullptr) THROW_EXCEPTION(NoEnoughMemoryException, "There is no memory to create string..."); strncpy(str, m_str, index); strcpy(str + index, s); strcpy(str + index + size, m_str + index); @@ -79,7 +92,9 @@ String &String::insert(size_t index, const char *s) { return *this; } -String &String::insert(size_t index, const String &s) { return insert(index, s.m_str); } +String &String::insert(size_t index, const String &s) { + return insert(index, s.m_str); +} String &String::trim() { size_t begin = 0, end = m_length - 1; @@ -99,9 +114,13 @@ String &String::trim() { return *this; } -int String::indexOf(const char *s) const { return kmp(m_str, s); } +int String::indexOf(const char *s) const { + return kmp(m_str, s); +} -int String::indexOf(const String &s) const { return indexOf(s.m_str); } +int String::indexOf(const String &s) const { + return indexOf(s.m_str); +} String &String::remove(size_t index, size_t length) { if (index >= m_length) THROW_EXCEPTION(InvalidParameterException, "Index is invalid..."); @@ -120,7 +139,9 @@ String &String::remove(const char *s) { return *this; } -String &String::remove(const String &s) { return remove(s.m_str); } +String &String::remove(const String &s) { + return remove(s.m_str); +} String &String::replace(const char *t, const char *s) { auto pos = indexOf(t); @@ -131,11 +152,17 @@ String &String::replace(const char *t, const char *s) { return *this; } -String &String::replace(const String &t, const char *s) { return replace(t.m_str, s); } +String &String::replace(const String &t, const char *s) { + return replace(t.m_str, s); +} -String &String::replace(const char *t, const String &s) { return replace(t, s.m_str); } +String &String::replace(const char *t, const String &s) { + return replace(t, s.m_str); +} -String &String::replace(const String &t, const String &s) { return replace(t.m_str, s.m_str); } +String &String::replace(const String &t, const String &s) { + return replace(t.m_str, s.m_str); +} String String::substr(size_t index, size_t length) const { if (index >= m_length) THROW_EXCEPTION(InvalidParameterException, "Parameter index is invalid..."); @@ -154,23 +181,41 @@ char &String::operator[](size_t index) { return m_str[index]; } -char String::operator[](size_t index) const { return const_cast(*this)[index]; } +char String::operator[](size_t index) const { + return const_cast(*this)[index]; +} -bool String::operator<(const char *str) const { return (strcmp(m_str, str) < 0); } +bool String::operator<(const char *str) const { + return (strcmp(m_str, str) < 0); +} -bool String::operator<(const String &str) const { return operator<(str.m_str); } +bool String::operator<(const String &str) const { + return operator<(str.m_str); +} -bool String::operator>=(const char *str) const { return !(*this < str); } +bool String::operator>=(const char *str) const { + return !(*this < str); +} -bool String::operator>=(const String &str) const { return !(*this < str); } +bool String::operator>=(const String &str) const { + return !(*this < str); +} -bool String::operator>(const char *str) const { return (strcmp(m_str, str) > 0); } +bool String::operator>(const char *str) const { + return (strcmp(m_str, str) > 0); +} -bool String::operator>(const String &str) const { return operator>(str.m_str); } +bool String::operator>(const String &str) const { + return operator>(str.m_str); +} -bool String::operator<=(const char *str) const { return !(*this > str); } +bool String::operator<=(const char *str) const { + return !(*this > str); +} -bool String::operator<=(const String &str) const { return !(*this > str); } +bool String::operator<=(const String &str) const { + return !(*this > str); +} bool String::operator==(const char *str) const { if (str == nullptr && m_str == nullptr) return true; @@ -178,11 +223,17 @@ bool String::operator==(const char *str) const { return (strcmp(m_str, str) == 0); } -bool String::operator==(const String &str) const { return operator==(str.m_str); } +bool String::operator==(const String &str) const { + return operator==(str.m_str); +} -bool String::operator!=(const char *str) const { return !(*this == str); } +bool String::operator!=(const char *str) const { + return !(*this == str); +} -bool String::operator!=(const String &str) const { return !(*this == str); } +bool String::operator!=(const String &str) const { + return !(*this == str); +} String &String::operator+=(const char *str) { if (str != nullptr) { @@ -199,7 +250,9 @@ String &String::operator+=(const char *str) { return *this; } -String &String::operator+=(const String &str) { return operator+=(str.m_str); } +String &String::operator+=(const String &str) { + return operator+=(str.m_str); +} String String::operator+(const char *str) const { String ret(*this); @@ -207,11 +260,17 @@ String String::operator+(const char *str) const { return ret; } -String String::operator+(const String &str) const { return operator+(str.m_str); } +String String::operator+(const String &str) const { + return operator+(str.m_str); +} -String &String::operator-=(const char *str) { return remove(str); } +String &String::operator-=(const char *str) { + return remove(str); +} -String &String::operator-=(const String &str) { return remove(str); } +String &String::operator-=(const String &str) { + return remove(str); +} String String::operator-(const char *str) const { String ret(*this); diff --git a/UnitTest/DataStructure/BinaryTreeTest.cpp b/UnitTest/DataStructure/BinaryTreeTest.cpp index 33b8848..dfe01a1 100644 --- a/UnitTest/DataStructure/BinaryTreeTest.cpp +++ b/UnitTest/DataStructure/BinaryTreeTest.cpp @@ -77,11 +77,17 @@ public: size_t levelOrder[11]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; }; BOOST_AUTO_TEST_SUITE(BinaryTreeTestCase) -BOOST_FIXTURE_TEST_CASE(Count, BinaryTreeTest) { BOOST_CHECK_EQUAL(tree.count(), 11); } +BOOST_FIXTURE_TEST_CASE(Count, BinaryTreeTest) { + BOOST_CHECK_EQUAL(tree.count(), 11); +} -BOOST_FIXTURE_TEST_CASE(Height, BinaryTreeTest) { BOOST_CHECK_EQUAL(tree.height(), 4); } +BOOST_FIXTURE_TEST_CASE(Height, BinaryTreeTest) { + BOOST_CHECK_EQUAL(tree.height(), 4); +} -BOOST_FIXTURE_TEST_CASE(Degree, BinaryTreeTest) { BOOST_CHECK_EQUAL(tree.degree(), 2); } +BOOST_FIXTURE_TEST_CASE(Degree, BinaryTreeTest) { + BOOST_CHECK_EQUAL(tree.degree(), 2); +} BOOST_FIXTURE_TEST_CASE(FindWithValue, BinaryTreeTest) { auto node = tree.find(5); @@ -230,44 +236,84 @@ BOOST_FIXTURE_TEST_CASE(Add, BinaryTreeTest) { BOOST_FIXTURE_TEST_CASE(PreorderThreaded, BinaryTreeTest) { auto head = tree.threaded(BinaryTree::Preorder); size_t index = 0; - while (head != nullptr) { - BOOST_CHECK_EQUAL(head->value, preOrder[index++]); - head = head->right; + + BinaryTreeNode *pos = head; + while (pos != nullptr) { + BOOST_CHECK_EQUAL(pos->value, preOrder[index++]); + pos = pos->right; } BOOST_CHECK_EQUAL(index, 11); BOOST_CHECK_EQUAL(tree.count(), 0); + + // 释放资源 + pos = head; + while (pos != nullptr) { + auto temp = pos; + pos = pos->right; + delete temp; + } } BOOST_FIXTURE_TEST_CASE(InorderThreaded, BinaryTreeTest) { auto head = tree.threaded(BinaryTree::Inorder); size_t index = 0; - while (head != nullptr) { - BOOST_CHECK_EQUAL(head->value, inOrder[index++]); - head = head->right; + + BinaryTreeNode *pos = head; + while (pos != nullptr) { + BOOST_CHECK_EQUAL(pos->value, inOrder[index++]); + pos = pos->right; } BOOST_CHECK_EQUAL(index, 11); BOOST_CHECK_EQUAL(tree.count(), 0); + + // 释放资源 + pos = head; + while (pos != nullptr) { + auto temp = pos; + pos = pos->right; + delete temp; + } } BOOST_FIXTURE_TEST_CASE(PostorderThreaded, BinaryTreeTest) { auto head = tree.threaded(BinaryTree::Postorder); size_t index = 0; - while (head != nullptr) { - BOOST_CHECK_EQUAL(head->value, postOrder[index++]); - head = head->right; + + BinaryTreeNode *pos = head; + while (pos != nullptr) { + BOOST_CHECK_EQUAL(pos->value, postOrder[index++]); + pos = pos->right; } BOOST_CHECK_EQUAL(index, 11); BOOST_CHECK_EQUAL(tree.count(), 0); + + // 释放资源 + pos = head; + while (pos != nullptr) { + auto temp = pos; + pos = pos->right; + delete temp; + } } BOOST_FIXTURE_TEST_CASE(LevelorderThreaded, BinaryTreeTest) { auto head = tree.threaded(BinaryTree::Levelorder); size_t index = 0; - while (head != nullptr) { - BOOST_CHECK_EQUAL(head->value, levelOrder[index++]); - head = head->right; + + BinaryTreeNode *pos = head; + while (pos != nullptr) { + BOOST_CHECK_EQUAL(pos->value, levelOrder[index++]); + pos = pos->right; } BOOST_CHECK_EQUAL(index, 11); BOOST_CHECK_EQUAL(tree.count(), 0); + + // 释放资源 + pos = head; + while (pos != nullptr) { + auto temp = pos; + pos = pos->right; + delete temp; + } } BOOST_AUTO_TEST_SUITE_END() diff --git a/UnitTest/Universal/DateTimeTest.cpp b/UnitTest/Universal/DateTimeTest.cpp index 339e6b9..60e5bb9 100644 --- a/UnitTest/Universal/DateTimeTest.cpp +++ b/UnitTest/Universal/DateTimeTest.cpp @@ -53,10 +53,9 @@ BOOST_AUTO_TEST_CASE(TomorrowTest) { } BOOST_AUTO_TEST_CASE(CurrentMSecsSinceEpoch) { - BOOST_CHECK_EQUAL(DateTime::currentMSecsSinceEpoch(), - std::chrono::time_point_cast(std::chrono::system_clock::now()) - .time_since_epoch() - .count()); + auto time1 = DateTime::currentMSecsSinceEpoch(); + auto time2 = std::chrono::time_point_cast(std::chrono::system_clock::now()).time_since_epoch().count(); + BOOST_TEST(std::abs(time1 - time2) < 5); } BOOST_AUTO_TEST_CASE(ParseTimeString) { diff --git a/Universal/CMakeLists.txt b/Universal/CMakeLists.txt index 3940a8b..c8d9e2c 100644 --- a/Universal/CMakeLists.txt +++ b/Universal/CMakeLists.txt @@ -30,6 +30,12 @@ else() cmake_path(GET CMAKE_CURRENT_SOURCE_DIR PARENT_PATH KYLIN_CORE_INCLUDE_PATH) endif() +if(DISABLE_LOG) +target_compile_definitions(Universal + PUBLIC DISABLE_LOG +) +endif() + target_include_directories(Universal INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} INTERFACE ${KYLIN_CORE_INCLUDE_PATH} diff --git a/Universal/MessageManager.cpp b/Universal/MessageManager.cpp index bc46b89..c93895e 100644 --- a/Universal/MessageManager.cpp +++ b/Universal/MessageManager.cpp @@ -10,7 +10,9 @@ MessageManager::~MessageManager() { } void MessageManager::run() { +#ifndef DISABLE_LOG LOG(trace) << "message runner[" << std::this_thread::get_id() << "] start..."; +#endif while (!m_exit) { if (m_params.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); @@ -20,7 +22,9 @@ void MessageManager::run() { callExecutor(topic, std::move(args)); m_params.pop(); } +#ifndef DISABLE_LOG LOG(trace) << "message runner exit..."; +#endif } void MessageManager::callExecutor(const std::string &signature, std::any &¶meter) { diff --git a/Universal/MessageManager.inl b/Universal/MessageManager.inl index 5e96ae2..62a1c43 100644 --- a/Universal/MessageManager.inl +++ b/Universal/MessageManager.inl @@ -66,7 +66,9 @@ template void MessageManager::registerTopic(const std::string_view &topic, Function &&f) { auto signature = formatTopicWithFunction(topic); m_executors.emplace(signature, executorWrapper(std::move(f))); +#ifndef DISABLE_LOG LOG(debug) << "register message,topic: " << signature; +#endif } template @@ -113,7 +115,9 @@ template void MessageManager::sendAsyncMessage(const std::string_view &topic, Args &&...args) { auto signature = formatTopicWithParameters(topic, std::forward(args)...); m_params.push({signature, std::make_tuple(std::forward(args)...)}); +#ifndef DISABLE_LOG LOG(debug) << "call async message,topic: " << signature; +#endif } template