From 499b9d1be85867a03973b69c5dbbeb22f51f57a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Sat, 21 Oct 2023 17:51:49 +0800 Subject: [PATCH] =?UTF-8?q?=EF=BB=BFFix=20various=20memory=20leaks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit prusa3d/PrusaSlicer@deb17c59204db6d5308899cb4c428a23fa400851) --- src/libslic3r/ExtrusionEntityCollection.cpp | 7 +-- src/libslic3r/Semver.hpp | 28 +++++++-- src/slic3r/GUI/BedShapeDialog.hpp | 1 + src/slic3r/GUI/GLCanvas3D.cpp | 24 +++++--- src/slic3r/GUI/GUI_ObjectList.cpp | 1 + src/slic3r/GUI/GUI_ObjectList.hpp | 2 +- src/slic3r/GUI/Tab.cpp | 67 +++++++++++---------- 7 files changed, 79 insertions(+), 51 deletions(-) diff --git a/src/libslic3r/ExtrusionEntityCollection.cpp b/src/libslic3r/ExtrusionEntityCollection.cpp index 391ac2d587..e6ae1edd4d 100644 --- a/src/libslic3r/ExtrusionEntityCollection.cpp +++ b/src/libslic3r/ExtrusionEntityCollection.cpp @@ -56,12 +56,9 @@ ExtrusionEntityCollection::operator ExtrusionPaths() const return paths; } -ExtrusionEntity* ExtrusionEntityCollection::clone() const +ExtrusionEntity *ExtrusionEntityCollection::clone() const { - ExtrusionEntityCollection* coll = new ExtrusionEntityCollection(*this); - for (size_t i = 0; i < coll->entities.size(); ++i) - coll->entities[i] = this->entities[i]->clone(); - return coll; + return new ExtrusionEntityCollection(*this); } void ExtrusionEntityCollection::reverse() diff --git a/src/libslic3r/Semver.hpp b/src/libslic3r/Semver.hpp index cdc96f108b..4d64b1c7db 100644 --- a/src/libslic3r/Semver.hpp +++ b/src/libslic3r/Semver.hpp @@ -110,10 +110,30 @@ public: void set_maj(int maj) { ver.major = maj; } void set_min(int min) { ver.minor = min; } void set_patch(int patch) { ver.patch = patch; } - void set_metadata(boost::optional meta) { ver.metadata = meta ? strdup(*meta) : nullptr; } - void set_metadata(const char *meta) { ver.metadata = meta ? strdup(meta) : nullptr; } - void set_prerelease(boost::optional pre) { ver.prerelease = pre ? strdup(*pre) : nullptr; } - void set_prerelease(const char *pre) { ver.prerelease = pre ? strdup(pre) : nullptr; } + void set_metadata(boost::optional meta) + { + if (ver.metadata) + free(ver.metadata); + ver.metadata = meta ? strdup(*meta) : nullptr; + } + void set_metadata(const char *meta) + { + if (ver.metadata) + free(ver.metadata); + ver.metadata = meta ? strdup(meta) : nullptr; + } + void set_prerelease(boost::optional pre) + { + if (ver.prerelease) + free(ver.prerelease); + ver.prerelease = pre ? strdup(*pre) : nullptr; + } + void set_prerelease(const char *pre) + { + if (ver.prerelease) + free(ver.prerelease); + ver.prerelease = pre ? strdup(pre) : nullptr; + } // Comparison bool operator<(const Semver &b) const { return ::semver_compare(ver, b.ver) == -1; } diff --git a/src/slic3r/GUI/BedShapeDialog.hpp b/src/slic3r/GUI/BedShapeDialog.hpp index 20201faf0f..912faf6bfb 100644 --- a/src/slic3r/GUI/BedShapeDialog.hpp +++ b/src/slic3r/GUI/BedShapeDialog.hpp @@ -18,6 +18,7 @@ namespace GUI { class ConfigOptionsGroup; using ConfigOptionsGroupShp = std::shared_ptr; +using ConfigOptionsGroupWkp = std::weak_ptr; struct BedShape { diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 175f2f6148..419e3b048a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -8703,10 +8703,14 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info(); // Remove empty volumes from the newly added volumes. - m_volumes.volumes.erase( - std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(), - [](const GLVolume *volume) { return volume->empty(); }), - m_volumes.volumes.end()); + { + for (auto ptr_it = m_volumes.volumes.begin() + volumes_cnt_initial; ptr_it != m_volumes.volumes.end(); ++ptr_it) + if ((*ptr_it)->empty()) { + delete *ptr_it; + *ptr_it = nullptr; + } + m_volumes.volumes.erase(std::remove(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(), nullptr), m_volumes.volumes.end()); + } for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) { GLVolume* v = m_volumes.volumes[i]; v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box()); @@ -8872,10 +8876,14 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info(); // Remove empty volumes from the newly added volumes. - m_volumes.volumes.erase( - std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(), - [](const GLVolume *volume) { return volume->empty(); }), - m_volumes.volumes.end()); + { + for (auto ptr_it = m_volumes.volumes.begin() + volumes_cnt_initial; ptr_it != m_volumes.volumes.end(); ++ptr_it) + if ((*ptr_it)->empty()) { + delete *ptr_it; + *ptr_it = nullptr; + } + m_volumes.volumes.erase(std::remove(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(), nullptr), m_volumes.volumes.end()); + } for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) { GLVolume* v = m_volumes.volumes[i]; v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box()); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 24f44a12a1..5e5eee3806 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -304,6 +304,7 @@ ObjectList::ObjectList(wxWindow* parent) : ObjectList::~ObjectList() { + delete m_objects_model; } void ObjectList::set_min_height() diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 125c748037..f4a6f0320a 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -205,7 +205,7 @@ private: public: ObjectList(wxWindow* parent); - ~ObjectList(); + ~ObjectList() override; void set_min_height(); void update_min_height(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 3ad2c440c3..ffacda6d63 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2572,8 +2572,8 @@ bool Tab::validate_custom_gcode(const wxString& title, const std::string& gcode) return !invalid; } -static void validate_custom_gcode_cb(Tab* tab, ConfigOptionsGroupShp opt_group, const t_config_option_key& opt_key, const boost::any& value) { - tab->validate_custom_gcodes_was_shown = !Tab::validate_custom_gcode(opt_group->title, boost::any_cast(value)); +static void validate_custom_gcode_cb(Tab* tab, const wxString& title, const t_config_option_key& opt_key, const boost::any& value) { + tab->validate_custom_gcodes_was_shown = !Tab::validate_custom_gcode(title, boost::any_cast(value)); tab->update_dirty(); tab->on_value_change(opt_key, value); } @@ -2590,18 +2590,19 @@ void TabFilament::add_filament_overrides_page() //BBS line = optgroup->create_single_option_line(optgroup->get_option(opt_key)); - line.near_label_widget = [this, optgroup, opt_key, opt_index](wxWindow* parent) { + line.near_label_widget = [this, optgroup_wk = ConfigOptionsGroupWkp(optgroup), opt_key, opt_index](wxWindow* parent) { wxCheckBox* check_box = new wxCheckBox(parent, wxID_ANY, ""); - check_box->Bind(wxEVT_CHECKBOX, [optgroup, opt_key, opt_index](wxCommandEvent& evt) { + check_box->Bind(wxEVT_CHECKBOX, [optgroup_wk, opt_key, opt_index](wxCommandEvent& evt) { const bool is_checked = evt.IsChecked(); - Field* field = optgroup->get_fieldc(opt_key, opt_index); - if (field != nullptr) { - field->toggle(is_checked); - if (is_checked) - field->set_last_meaningful_value(); - else - field->set_na_value(); + if (auto optgroup_sh = optgroup_wk.lock(); optgroup_sh) { + if (Field *field = optgroup_sh->get_fieldc(opt_key, opt_index); field != nullptr) { + field->toggle(is_checked); + if (is_checked) + field->set_last_meaningful_value(); + else + field->set_na_value(); + } } }, check_box->GetId()); @@ -2758,7 +2759,7 @@ void TabFilament::build() line.append_option(optgroup->get_option("textured_plate_temp")); optgroup->append_line(line); - optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value) + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { DynamicPrintConfig& filament_config = wxGetApp().preset_bundle->filaments.get_edited_preset().config; @@ -2853,8 +2854,8 @@ void TabFilament::build() page = add_options_page(L("Advanced"), "advanced"); optgroup = page->new_optgroup(L("Filament start G-code"), L"param_gcode", 0); - optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { - validate_custom_gcode_cb(this, optgroup, opt_key, value); + optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode_cb(this, optgroup_title, opt_key, value); }; option = optgroup->get_option("filament_start_gcode"); option.opt.full_width = true; @@ -2863,8 +2864,8 @@ void TabFilament::build() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Filament end G-code"), L"param_gcode", 0); - optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { - validate_custom_gcode_cb(this, optgroup, opt_key, value); + optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode_cb(this, optgroup_title, opt_key, value); }; option = optgroup->get_option("filament_end_gcode"); option.opt.full_width = true; @@ -3170,8 +3171,8 @@ void TabPrinter::build_fff() const int notes_field_height = 25; // 250 page = add_options_page(L("Machine gcode"), "cog"); optgroup = page->new_optgroup(L("Machine start G-code"), L"param_gcode", 0); - optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { - validate_custom_gcode_cb(this, optgroup, opt_key, value); + optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode_cb(this, optgroup_title, opt_key, value); }; option = optgroup->get_option("machine_start_gcode"); option.opt.full_width = true; @@ -3180,8 +3181,8 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Machine end G-code"), L"param_gcode", 0); - optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { - validate_custom_gcode_cb(this, optgroup, opt_key, value); + optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode_cb(this, optgroup_title, opt_key, value); }; option = optgroup->get_option("machine_end_gcode"); option.opt.full_width = true; @@ -3190,8 +3191,8 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Before layer change G-code"),"param_gcode", 0); - optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { - validate_custom_gcode_cb(this, optgroup, opt_key, value); + optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode_cb(this, optgroup_title, opt_key, value); }; option = optgroup->get_option("before_layer_change_gcode"); option.opt.full_width = true; @@ -3200,8 +3201,8 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Layer change G-code"), L"param_gcode", 0); - optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { - validate_custom_gcode_cb(this, optgroup, opt_key, value); + optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode_cb(this, optgroup_title, opt_key, value); }; option = optgroup->get_option("layer_change_gcode"); option.opt.full_width = true; @@ -3210,8 +3211,8 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Time lapse G-code"), L"param_gcode", 0); - optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { - validate_custom_gcode_cb(this, optgroup, opt_key, value); + optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode_cb(this, optgroup_title, opt_key, value); }; option = optgroup->get_option("time_lapse_gcode"); option.opt.full_width = true; @@ -3220,8 +3221,8 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Change filament G-code"), L"param_gcode", 0); - optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { - validate_custom_gcode_cb(this, optgroup, opt_key, value); + optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode_cb(this, optgroup_title, opt_key, value); }; option = optgroup->get_option("change_filament_gcode"); option.opt.full_width = true; @@ -3230,8 +3231,8 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Pause G-code"), L"param_gcode", 0); - optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { - validate_custom_gcode_cb(this, optgroup, opt_key, value); + optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode_cb(this, optgroup_title, opt_key, value); }; option = optgroup->get_option("machine_pause_gcode"); option.opt.is_code = true; @@ -3239,8 +3240,8 @@ void TabPrinter::build_fff() optgroup->append_single_option_line(option); optgroup = page->new_optgroup(L("Template Custom G-code"), L"param_gcode", 0); - optgroup->m_on_change = [this, optgroup](const t_config_option_key& opt_key, const boost::any& value) { - validate_custom_gcode_cb(this, optgroup, opt_key, value); + optgroup->m_on_change = [this, &optgroup_title = optgroup->title](const t_config_option_key& opt_key, const boost::any& value) { + validate_custom_gcode_cb(this, optgroup_title, opt_key, value); }; option = optgroup->get_option("template_custom_gcode"); option.opt.is_code = true; @@ -3468,7 +3469,7 @@ if (is_marlin_flavor) auto optgroup = page->new_optgroup(L("Single extruder multimaterial setup")); optgroup->append_single_option_line("single_extruder_multi_material", "semm"); // Orca: we only support Single Extruder Multi Material, so it's always enabled - // optgroup->m_on_change = [this, optgroup](const t_config_option_key &opt_key, const boost::any &value) { + // optgroup->m_on_change = [this](const t_config_option_key &opt_key, const boost::any &value) { // wxTheApp->CallAfter([this, opt_key, value]() { // if (opt_key == "single_extruder_multi_material") { // build_unregular_pages();