From 6a534ba6352ad5e19c3e74a5f2e9e2590bd98062 Mon Sep 17 00:00:00 2001 From: Pasha Bibko <156938226+PashaBibko@users.noreply.github.com> Date: Wed, 23 Jul 2025 18:22:24 +0100 Subject: [PATCH] Stopped memory leak with transferring tokens --- Lexer/inc/Token.h | 10 ++++++++++ Lexer/src/Token.cpp | 30 ++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Lexer/inc/Token.h b/Lexer/inc/Token.h index b354322..bfc0892 100644 --- a/Lexer/inc/Token.h +++ b/Lexer/inc/Token.h @@ -92,6 +92,16 @@ namespace LXC::Lexer // Constructor to set the data of the token for more complex token types // Token(const LexerContext& ctx, uint32_t start, unsigned short len, TokenType _type); + // Copy constructor // + Token(const Token& other); + + // Move constructor (transfers memory allocated) // + Token(Token&& other) noexcept; + + // Cannot use these as members are const // + Token& operator=(const Token&) = delete; + Token& operator=(Token&&) = delete; + // Deconstructor to clean up the allocated memory // ~Token(); diff --git a/Lexer/src/Token.cpp b/Lexer/src/Token.cpp index c1a5a39..c1b4dbc 100644 --- a/Lexer/src/Token.cpp +++ b/Lexer/src/Token.cpp @@ -21,14 +21,35 @@ namespace LXC::Lexer } } + // Copy constructor // + Token::Token(const Token& other) : + type(other.type), length(other.length), index(other.index), contents(nullptr) + { + if (other.contents != nullptr) + { + size_t len = std::strlen(other.contents) + 1; // Adds one for null-terminator + contents = new char[len]; + std::memcpy(contents, other.contents, len); + } + } + + // Move constructor (transfers memory allocated) // + Token::Token(Token&& other) noexcept : + type(other.type), length(other.length), index(other.index), contents(other.contents) + { + // Stops the other from thinking it owns the memory // + other.contents = nullptr; + } + // Destructor to clean up the memory of the token that can be allocated // Token::~Token() { // Frees any allocated memory // - //if (contents != nullptr) - // delete[] contents; - - contents = nullptr; + if (contents != nullptr) _UNLIKELY + { + delete[] contents; + contents = nullptr; + } } // Helper macro for converting type to string // @@ -82,6 +103,7 @@ namespace LXC::Lexer std::ostringstream os; os << std::setw(25) << std::left << TokenTypeToCStr(type) << " | "; + // Prints the contents if they are not null // if (contents != nullptr) os << std::setw(25) << std::left << std::string('"' + std::string(contents) + '"'); else