fix mem leak.

This commit is contained in:
amass 2024-09-16 01:32:40 +08:00
parent d0a6ac56a4
commit e76a8ce1b7
7 changed files with 170 additions and 51 deletions

View File

@ -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)

View File

@ -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<char *>(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<String &>(*this)[index]; }
char String::operator[](size_t index) const {
return const_cast<String &>(*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);

View File

@ -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<size_t>::Preorder);
size_t index = 0;
while (head != nullptr) {
BOOST_CHECK_EQUAL(head->value, preOrder[index++]);
head = head->right;
BinaryTreeNode<size_t> *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<size_t>::Inorder);
size_t index = 0;
while (head != nullptr) {
BOOST_CHECK_EQUAL(head->value, inOrder[index++]);
head = head->right;
BinaryTreeNode<size_t> *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<size_t>::Postorder);
size_t index = 0;
while (head != nullptr) {
BOOST_CHECK_EQUAL(head->value, postOrder[index++]);
head = head->right;
BinaryTreeNode<size_t> *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<size_t>::Levelorder);
size_t index = 0;
while (head != nullptr) {
BOOST_CHECK_EQUAL(head->value, levelOrder[index++]);
head = head->right;
BinaryTreeNode<size_t> *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()

View File

@ -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::milliseconds>(std::chrono::system_clock::now())
.time_since_epoch()
.count());
auto time1 = DateTime::currentMSecsSinceEpoch();
auto time2 = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
BOOST_TEST(std::abs(time1 - time2) < 5);
}
BOOST_AUTO_TEST_CASE(ParseTimeString) {

View File

@ -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}

View File

@ -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 &&parameter) {

View File

@ -66,7 +66,9 @@ template <typename Function>
void MessageManager::registerTopic(const std::string_view &topic, Function &&f) {
auto signature = formatTopicWithFunction<Function>(topic);
m_executors.emplace(signature, executorWrapper(std::move(f)));
#ifndef DISABLE_LOG
LOG(debug) << "register message,topic: " << signature;
#endif
}
template <typename Function, typename... Args>
@ -113,7 +115,9 @@ template <typename... Args>
void MessageManager::sendAsyncMessage(const std::string_view &topic, Args &&...args) {
auto signature = formatTopicWithParameters(topic, std::forward<Args>(args)...);
m_params.push({signature, std::make_tuple(std::forward<Args>(args)...)});
#ifndef DISABLE_LOG
LOG(debug) << "call async message,topic: " << signature;
#endif
}
template <typename Function, typename... Args>