From 7878943384a7549ce844a5474886ef3ddcf9aa26 Mon Sep 17 00:00:00 2001 From: Vladislav Kalinin Date: Fri, 8 Nov 2024 03:41:32 +0100 Subject: [PATCH] Avoid memory allocations with `new` (replaced with smart pointers) --- coffi/coffi.hpp | 108 ++++++++++++++++++-------------------- coffi/coffi_directory.hpp | 27 +++++----- coffi/coffi_headers.hpp | 27 +++++----- coffi/coffi_section.hpp | 28 +++++----- coffi/coffi_strings.hpp | 51 +++++++++--------- 5 files changed, 114 insertions(+), 127 deletions(-) diff --git a/coffi/coffi.hpp b/coffi/coffi.hpp index bd47fdd..9806070 100644 --- a/coffi/coffi.hpp +++ b/coffi/coffi.hpp @@ -75,7 +75,7 @@ class coffi : public coffi_strings, //--------------------------------------------------------------------- coffi() : coffi_strings{}, architecture_{COFFI_ARCHITECTURE_NONE}, - dos_header_{0}, coff_header_{0}, optional_header_{0}, win_header_{0}, + dos_header_{}, coff_header_{}, optional_header_{}, win_header_{}, directories_{this} { create(COFFI_ARCHITECTURE_PE); @@ -119,7 +119,7 @@ class coffi : public coffi_strings, stream.seekg(0); architecture_ = COFFI_ARCHITECTURE_NONE; - dos_header_ = new dos_header; + dos_header_ = std::make_unique(); if (dos_header_->load(stream)) { // It is an EXE architecture_ = COFFI_ARCHITECTURE_PE; @@ -131,7 +131,7 @@ class coffi : public coffi_strings, } // Try to read a PE header - coff_header_ = new coff_header_impl; + coff_header_ = std::make_unique(); if (coff_header_->load(stream)) { // Check the machine @@ -180,7 +180,7 @@ class coffi : public coffi_strings, // Try to read a TI header if (architecture_ == COFFI_ARCHITECTURE_NONE) { - coff_header_ = new coff_header_impl_ti; + coff_header_ = std::make_unique(); stream.seekg(0); if (!coff_header_->load(stream)) { clean(); @@ -200,7 +200,7 @@ class coffi : public coffi_strings, if (architecture_ == COFFI_ARCHITECTURE_NONE) { // The format is not recognized, default to PE format header - coff_header_ = new coff_header_impl; + coff_header_ = std::make_unique(); stream.seekg(0); if (!coff_header_->load(stream)) { clean(); @@ -211,15 +211,15 @@ class coffi : public coffi_strings, if (coff_header_->get_optional_header_size()) { if (architecture_ == COFFI_ARCHITECTURE_PE) { std::streampos pos = stream.tellg(); - optional_header_ = new optional_header_impl_pe; + optional_header_ = std::make_unique(); if (!optional_header_->load(stream)) { clean(); return false; } if (optional_header_->get_magic() == OH_MAGIC_PE32PLUS) { - delete optional_header_; + optional_header_.reset(); stream.seekg(pos); - optional_header_ = new optional_header_impl_pe_plus; + optional_header_ = std::make_unique(); if (!optional_header_->load(stream)) { clean(); return false; @@ -228,13 +228,13 @@ class coffi : public coffi_strings, } else { if (architecture_ == COFFI_ARCHITECTURE_NONE) { - optional_header_ = new optional_header_impl_pe; + optional_header_ = std::make_unique(); } if (architecture_ == COFFI_ARCHITECTURE_CEVA) { - optional_header_ = new optional_header_impl_pe; + optional_header_ = std::make_unique(); } if (architecture_ == COFFI_ARCHITECTURE_TI) { - optional_header_ = new optional_header_impl_ti; + optional_header_ = std::make_unique(); } if (!optional_header_->load(stream)) { clean(); @@ -244,19 +244,17 @@ class coffi : public coffi_strings, if (architecture_ == COFFI_ARCHITECTURE_PE) { if (optional_header_->get_magic() == OH_MAGIC_PE32PLUS) { - win_header_ = new win_header_impl; + win_header_ = std::make_unique>(); } else if (optional_header_->get_magic() == OH_MAGIC_PE32 || optional_header_->get_magic() == OH_MAGIC_PE32ROM) { - win_header_ = new win_header_impl; + win_header_ = std::make_unique>(); } if (win_header_) { if (!win_header_->load(stream)) { - delete optional_header_; - optional_header_ = 0; - delete win_header_; - win_header_ = 0; + optional_header_.reset(); + win_header_.reset(); clean(); return false; } @@ -271,12 +269,12 @@ class coffi : public coffi_strings, } std::streampos pos = stream.tellg(); - if (!load_strings(stream, coff_header_)) { + if (!load_strings(stream, coff_header_.get())) { clean(); return false; } - if (!load_symbols(stream, coff_header_)) { + if (!load_symbols(stream, coff_header_.get())) { clean(); return false; } @@ -357,17 +355,17 @@ class coffi : public coffi_strings, architecture_ = architecture; if (architecture_ == COFFI_ARCHITECTURE_PE) { - coff_header_ = new coff_header_impl; + coff_header_ = std::make_unique(); coff_header_->set_machine(IMAGE_FILE_MACHINE_I386); } if (architecture_ == COFFI_ARCHITECTURE_CEVA) { - coff_header_ = new coff_header_impl; + coff_header_ = std::make_unique(); coff_header_->set_machine(CEVA_MACHINE_XC4210_OBJ); } if (architecture_ == COFFI_ARCHITECTURE_TI) { - coff_header_ = new coff_header_impl_ti; + coff_header_ = std::make_unique(); coff_header_->set_target_id(TMS320C2800); } } @@ -389,27 +387,27 @@ class coffi : public coffi_strings, void create_optional_header(uint16_t magic = OH_MAGIC_PE32) { if (dos_header_) { - delete dos_header_; + dos_header_.reset(); } if (optional_header_) { - delete optional_header_; + optional_header_.reset(); } if (architecture_ == COFFI_ARCHITECTURE_PE) { - dos_header_ = new dos_header; + dos_header_ = std::make_unique(); if (magic == OH_MAGIC_PE32PLUS) { - optional_header_ = new optional_header_impl_pe_plus; + optional_header_ = std::make_unique(); } else { - optional_header_ = new optional_header_impl_pe; + optional_header_ = std::make_unique(); } optional_header_->set_magic(magic); create_win_header(); } if (architecture_ == COFFI_ARCHITECTURE_CEVA) { - optional_header_ = new optional_header_impl_pe; + optional_header_ = std::make_unique(); } if (architecture_ == COFFI_ARCHITECTURE_TI) { - optional_header_ = new optional_header_impl_ti; + optional_header_ = std::make_unique(); } coff_header_->set_optional_header_size(narrow_cast( optional_header_->get_sizeof() + win_header_->get_sizeof() + @@ -421,38 +419,38 @@ class coffi : public coffi_strings, * * @return nullptr if the MS-DOS header is not initialized (see create_optional_header()), or not loaded (see load()), or not relevant for the architecture. */ - dos_header* get_msdos_header() { return dos_header_; } + dos_header* get_msdos_header() { return dos_header_.get(); } //--------------------------------------------------------------------- /*! @copydoc get_msdos_header() */ - const dos_header* get_msdos_header() const { return dos_header_; } + const dos_header* get_msdos_header() const { return dos_header_.get(); } //--------------------------------------------------------------------- /*! @brief Returns the COFF header * * @return nullptr if the coffi object is not initialized (see create()), or not loaded (see load()). */ - coff_header* get_header() { return coff_header_; } + coff_header* get_header() { return coff_header_.get(); } //--------------------------------------------------------------------- /*! @copydoc get_header() */ - const coff_header* get_header() const { return coff_header_; } + const coff_header* get_header() const { return coff_header_.get(); } //--------------------------------------------------------------------- /*! @brief Returns the optional COFF header * * @return nullptr if the optional COFF header is not initialized (see create_optional_header()), or not loaded (see load()). */ - optional_header* get_optional_header() { return optional_header_; } + optional_header* get_optional_header() { return optional_header_.get(); } //--------------------------------------------------------------------- /*! @copydoc get_optional_header() */ const optional_header* get_optional_header() const { - return optional_header_; + return optional_header_.get(); } //--------------------------------------------------------------------- @@ -460,12 +458,12 @@ class coffi : public coffi_strings, * * @return nullptr if the Windows NT header is not initialized (see create_optional_header()), or not loaded (see load()), or not relevant for the architecture. */ - win_header* get_win_header() { return win_header_; } + win_header* get_win_header() { return win_header_.get(); } //--------------------------------------------------------------------- /*! @copydoc get_win_header() */ - const win_header* get_win_header() const { return win_header_; } + const win_header* get_win_header() const { return win_header_.get(); } //--------------------------------------------------------------------- /*! @brief Returns a list of the COFF sections @@ -598,23 +596,19 @@ class coffi : public coffi_strings, void clean() { if (dos_header_) { - delete dos_header_; - dos_header_ = 0; + dos_header_.reset(); } if (coff_header_) { - delete coff_header_; - coff_header_ = 0; + coff_header_.reset(); } if (optional_header_) { - delete optional_header_; - optional_header_ = 0; + optional_header_.reset(); } if (win_header_) { - delete win_header_; - win_header_ = 0; + win_header_.reset(); } clean_unused_spaces(); @@ -631,14 +625,14 @@ class coffi : public coffi_strings, void create_win_header() { if (win_header_) { - delete win_header_; + win_header_.reset(); } if (optional_header_->get_magic() == OH_MAGIC_PE32PLUS) { - win_header_ = new win_header_impl; + win_header_ = std::make_unique>(); } else if (optional_header_->get_magic() == OH_MAGIC_PE32 || optional_header_->get_magic() == OH_MAGIC_PE32ROM) { - win_header_ = new win_header_impl; + win_header_ = std::make_unique>(); } } @@ -1060,15 +1054,15 @@ class coffi : public coffi_strings, }; //--------------------------------------------------------------------- - coffi_architecture_t architecture_; - dos_header* dos_header_; - coff_header* coff_header_; - optional_header* optional_header_; - win_header* win_header_; - directories directories_; - sections sections_; - std::vector unused_spaces_; - std::vector data_pages_; + coffi_architecture_t architecture_; + std::unique_ptr dos_header_; + std::unique_ptr coff_header_; + std::unique_ptr optional_header_; + std::unique_ptr win_header_; + directories directories_; + sections sections_; + std::vector unused_spaces_; + std::vector data_pages_; }; } // namespace COFFI diff --git a/coffi/coffi_directory.hpp b/coffi/coffi_directory.hpp index 1913beb..968e12a 100644 --- a/coffi/coffi_directory.hpp +++ b/coffi/coffi_directory.hpp @@ -53,7 +53,7 @@ class directory { public: //------------------------------------------------------------------------------ - directory(uint32_t index) : data_{nullptr}, index_{index} {} + directory(uint32_t index) : data_{}, index_{index} {} //------------------------------------------------------------------------------ //! Discards the copy constructor @@ -71,7 +71,7 @@ class directory uint32_t get_index() const { return index_; } //------------------------------------------------------------------------------ - const char* get_data() const { return data_; } + const char* get_data() const { return data_.get(); } //------------------------------------------------------------------------------ void set_data(const char* data, uint32_t size) @@ -87,13 +87,13 @@ class directory return; } - char* temp_buffer = new char[size]; + std::unique_ptr temp_buffer = std::make_unique(size); if (!temp_buffer) { set_size(0); return; } - std::copy(data, data + size, temp_buffer); - data_ = temp_buffer; + std::copy(data, data + size, temp_buffer.get()); + data_ = std::move(temp_buffer); set_size(size); } @@ -126,13 +126,13 @@ class directory return true; } if ((get_size() > 0) && (get_virtual_address() != 0)) { - char* temp_buffer = new char[get_size()]; + std::unique_ptr temp_buffer = std::make_unique(get_size()); stream.seekg(get_virtual_address()); - stream.read(temp_buffer, get_size()); + stream.read(temp_buffer.get(), get_size()); if (stream.gcount() != static_cast(get_size())) { return false; } - data_ = temp_buffer; + data_ = std::move(temp_buffer); } return true; } @@ -150,7 +150,7 @@ class directory return; } if (data_ && get_size() > 0) { - stream.write(data_, get_size()); + stream.write(data_.get(), get_size()); } } @@ -158,15 +158,14 @@ class directory void clean() { if (data_) { - delete[] data_; - data_ = nullptr; + data_.reset(); } } private: - image_data_directory header{}; - const char* data_; - uint32_t index_; + image_data_directory header{}; + std::unique_ptr data_; + uint32_t index_; }; /*! @brief List of image data directories diff --git a/coffi/coffi_headers.hpp b/coffi/coffi_headers.hpp index 5b293e1..e90146f 100644 --- a/coffi/coffi_headers.hpp +++ b/coffi/coffi_headers.hpp @@ -126,12 +126,12 @@ class dos_header if (get_pe_sign_location() > static_cast(sizeof(header))) { stub_size_ = get_pe_sign_location() - sizeof(header); - char* read_stub = new char[stub_size_]; + std::unique_ptr read_stub = std::make_unique(stub_size_); if (!read_stub) { return false; } - stream.read(read_stub, stub_size_); - stub_ = read_stub; + stream.read(read_stub.get(), stub_size_); + stub_ = std::move(read_stub); if (stream.gcount() != stub_size_) { return false; } @@ -155,7 +155,7 @@ class dos_header void save(std::ostream& stream) { stream.write(reinterpret_cast(&header), sizeof(header)); - stream.write(stub_, stub_size_); + stream.write(stub_.get(), stub_size_); stream.put(PEMAG2); stream.put(PEMAG3); stream.put(PEMAG4); @@ -163,7 +163,7 @@ class dos_header } //------------------------------------------------------------------------------ - virtual const char* get_stub() const { return stub_; } + virtual const char* get_stub() const { return stub_.get(); } //------------------------------------------------------------------------------ virtual uint32_t get_stub_size() const { return stub_size_; } @@ -172,17 +172,17 @@ class dos_header void set_stub(const char* data, uint32_t size) { if (stub_) { - delete[] stub_; + stub_.reset(); } stub_size_ = size; - char* new_stub = new char[stub_size_]; + std::unique_ptr new_stub = std::make_unique(stub_size_); if (!new_stub) { stub_size_ = 0; } else { - std::copy(data, data + size, new_stub); + std::copy(data, data + size, new_stub.get()); } - stub_ = new_stub; + stub_ = std::move(new_stub); } //------------------------------------------------------------------------------ @@ -197,16 +197,15 @@ class dos_header void clean() { if (stub_) { - delete[] stub_; - stub_ = 0; + stub_.reset(); } stub_size_ = 0; } //------------------------------------------------------------------------------ - msdos_header header; - const char* stub_; - int stub_size_; + msdos_header header; + std::unique_ptr stub_; + int stub_size_; }; //------------------------------------------------------------------------------ diff --git a/coffi/coffi_section.hpp b/coffi/coffi_section.hpp index b92117d..09ee373 100644 --- a/coffi/coffi_section.hpp +++ b/coffi/coffi_section.hpp @@ -153,7 +153,7 @@ template class section_impl_tmpl : public section } //------------------------------------------------------------------------------ - const char* get_data() const { return data_; } + const char* get_data() const { return data_.get(); } //------------------------------------------------------------------------------ void set_data(const char* data, uint32_t size) @@ -163,10 +163,10 @@ template class section_impl_tmpl : public section data_reserved_ = 0; } else { - data_ = new char[size]; + data_ = std::make_unique(size); if (data_) { data_reserved_ = size; - std::copy(data, data + size, data_); + std::copy(data, data + size, data_.get()); } else { data_reserved_ = 0; @@ -188,20 +188,19 @@ template class section_impl_tmpl : public section set_data(data, size); } if (get_data_size() + size <= data_reserved_) { - std::copy(data, data + size, data_ + get_data_size()); + std::copy(data, data + size, data_.get() + get_data_size()); } else { uint32_t new_data_size = 2 * (data_reserved_ + size); - char* new_data = new char[new_data_size]; + std::unique_ptr new_data = std::make_unique(new_data_size); if (!new_data) { size = 0; } else { data_reserved_ = new_data_size; - std::copy(data_, data_ + get_data_size(), new_data); - std::copy(data, data + size, new_data + get_data_size()); - delete[] data_; - data_ = new_data; + std::copy(data_.get(), data_.get() + get_data_size(), new_data.get()); + std::copy(data, data + size, new_data.get() + get_data_size()); + data_ = std::move(new_data); } } set_data_size(get_data_size() + size); @@ -246,12 +245,12 @@ template class section_impl_tmpl : public section if (!dont) { data_reserved_ = get_data_size(); if ((get_data_offset() != 0) && (data_reserved_ != 0)) { - data_ = new char[data_reserved_]; + data_ = std::make_unique(data_reserved_); if (!data_) { return false; } stream.seekg(get_data_offset()); - stream.read(data_, data_reserved_); + stream.read(data_.get(), data_reserved_); } } @@ -290,7 +289,7 @@ template class section_impl_tmpl : public section if (!data_ || get_data_offset() == 0) { return; } - stream.write(data_, get_data_size()); + stream.write(data_.get(), get_data_size()); } //------------------------------------------------------------------------------ @@ -328,8 +327,7 @@ template class section_impl_tmpl : public section void clean() { if (data_) { - delete[] data_; - data_ = 0; + data_.reset(); data_reserved_ = 0; } } @@ -356,7 +354,7 @@ template class section_impl_tmpl : public section T header; uint32_t index{}; std::string name; - char* data_; + std::unique_ptr data_; uint32_t data_reserved_; string_to_name_provider* stn_; symbol_provider* sym_; diff --git a/coffi/coffi_strings.hpp b/coffi/coffi_strings.hpp index f312543..455c1b1 100644 --- a/coffi/coffi_strings.hpp +++ b/coffi/coffi_strings.hpp @@ -41,7 +41,7 @@ class coffi_strings : public virtual string_to_name_provider { public: //--------------------------------------------------------------------- - coffi_strings() : strings_{0}, strings_reserved_{0} { clean_strings(); } + coffi_strings() : strings_{}, strings_reserved_{0} { clean_strings(); } //--------------------------------------------------------------------- //! Discards the copy constructor @@ -51,7 +51,7 @@ class coffi_strings : public virtual string_to_name_provider virtual ~coffi_strings() { clean_strings(); - delete[] strings_; + strings_.reset(); } //--------------------------------------------------------------------- @@ -60,7 +60,7 @@ class coffi_strings : public virtual string_to_name_provider if (!strings_) { return 0; } - return *reinterpret_cast(strings_); + return *reinterpret_cast(strings_.get()); } //--------------------------------------------------------------------- @@ -69,7 +69,7 @@ class coffi_strings : public virtual string_to_name_provider if (!strings_) { return; } - *reinterpret_cast(strings_) = value; + *reinterpret_cast(strings_.get()) = value; } //--------------------------------------------------------------------- @@ -101,16 +101,15 @@ class coffi_strings : public virtual string_to_name_provider } //--------------------------------------------------------------------- - virtual const char* get_strings() const { return strings_; } + virtual const char* get_strings() const { return strings_.get(); } //--------------------------------------------------------------------- virtual void set_strings(const char* str, uint32_t size) { - char* new_strings = new char[size]; + std::unique_ptr new_strings = std::make_unique(size); if (new_strings) { - std::copy(str, str + size, new_strings); - delete[] strings_; - strings_ = new_strings; + std::copy(str, str + size, new_strings.get()); + strings_ = std::move(new_strings); strings_reserved_ = size; set_strings_size(size); } @@ -122,9 +121,9 @@ class coffi_strings : public virtual string_to_name_provider void clean_strings() { if (strings_) { - delete[] strings_; + strings_.reset(); } - strings_ = new char[4]; + strings_ = std::make_unique(4); strings_reserved_ = 4; set_strings_size(4); } @@ -142,20 +141,19 @@ class coffi_strings : public virtual string_to_name_provider header->get_symbol_table_offset() + header->get_symbols_count() * sizeof(symbol_record); stream.seekg(strings_offset); - stream.read(strings_, 4); - char* new_strings = new char[get_strings_size()]; + stream.read(strings_.get(), 4); + std::unique_ptr new_strings = std::make_unique(get_strings_size()); if (!new_strings) { return false; } strings_reserved_ = get_strings_size(); stream.seekg(strings_offset); - stream.read(new_strings, get_strings_size()); + stream.read(new_strings.get(), get_strings_size()); if (stream.gcount() != static_cast(get_strings_size())) { return false; } - delete[] strings_; - strings_ = new_strings; + strings_ = std::move(new_strings); return true; } @@ -163,7 +161,7 @@ class coffi_strings : public virtual string_to_name_provider void save_strings(std::ostream& stream) const { if (strings_ && get_strings_size() > 4) { - stream.write(strings_, get_strings_size()); + stream.write(strings_.get(), get_strings_size()); } } @@ -175,11 +173,11 @@ class coffi_strings : public virtual string_to_name_provider if (*(uint32_t*)str == 0 && strings_) { uint32_t off = *(uint32_t*)(str + sizeof(uint32_t)); - ret = strings_ + off; + ret = strings_.get() + off; } else if (is_section && str[0] == '/') { int32_t off = std::atol(str + 1); - ret = strings_ + off; + ret = strings_.get() + off; } else { char dst[COFFI_NAME_SIZE + 1]; @@ -202,21 +200,20 @@ class coffi_strings : public virtual string_to_name_provider if (get_strings_size() + size > strings_reserved_) { uint32_t new_strings_reserved = 2 * (strings_reserved_ + narrow_cast(size)); - char* new_strings = new char[new_strings_reserved]; + std::unique_ptr new_strings = std::make_unique(new_strings_reserved); if (!new_strings) { offset = 0; size = 0; } else { strings_reserved_ = new_strings_reserved; - std::copy(strings_, strings_ + get_strings_size(), - new_strings); - delete[] strings_; - strings_ = new_strings; + std::copy(strings_.get(), strings_.get() + get_strings_size(), + new_strings.get()); + strings_ = std::move(new_strings); } } std::copy(name.c_str(), name.c_str() + size, - strings_ + get_strings_size()); + strings_.get() + get_strings_size()); set_strings_size(get_strings_size() + narrow_cast(size)); if (is_section) { str[0] = '/'; @@ -235,8 +232,8 @@ class coffi_strings : public virtual string_to_name_provider } //--------------------------------------------------------------------- - char* strings_; - uint32_t strings_reserved_; + std::unique_ptr strings_; + uint32_t strings_reserved_; }; } // namespace COFFI