diff --git a/src/engraving/dom/instrchange.cpp b/src/engraving/dom/instrchange.cpp index 9bc9a30c0ee8c..78aec1f7fe60d 100644 --- a/src/engraving/dom/instrchange.cpp +++ b/src/engraving/dom/instrchange.cpp @@ -79,6 +79,14 @@ InstrumentChange::~InstrumentChange() delete m_instrument; } +void InstrumentChange::setInstrument(Instrument* i) +{ + if (m_instrument != i) { + delete m_instrument; + m_instrument = i; + } +} + void InstrumentChange::setInstrument(const Instrument& i) { *m_instrument = i; diff --git a/src/engraving/dom/instrchange.h b/src/engraving/dom/instrchange.h index f1ccca6bc3d09..01ad99e9110d6 100644 --- a/src/engraving/dom/instrchange.h +++ b/src/engraving/dom/instrchange.h @@ -48,7 +48,7 @@ class InstrumentChange final : public TextBase InstrumentChange* clone() const override { return new InstrumentChange(*this); } Instrument* instrument() const { return m_instrument; } - void setInstrument(Instrument* i) { m_instrument = i; } + void setInstrument(Instrument* i); void setInstrument(Instrument&& i) { *m_instrument = i; } void setInstrument(const Instrument& i); void setupInstrument(const Instrument* instrument); diff --git a/src/engraving/dom/instrument.cpp b/src/engraving/dom/instrument.cpp index 36df940fd7d5c..cec4856e748c9 100644 --- a/src/engraving/dom/instrument.cpp +++ b/src/engraving/dom/instrument.cpp @@ -1041,7 +1041,10 @@ Instrument* InstrumentList::instrument(int tick) void InstrumentList::setInstrument(Instrument* instr, int tick) { - if (!insert({ tick, instr }).second) { + auto result = insert({ tick, instr }); + if (!result.second) { + // Key already exists, delete old instrument and replace + delete (*this)[tick]; (*this)[tick] = instr; } } diff --git a/src/engraving/dom/part.cpp b/src/engraving/dom/part.cpp index 758f9c096aede..c5f30e91b8c64 100644 --- a/src/engraving/dom/part.cpp +++ b/src/engraving/dom/part.cpp @@ -61,6 +61,18 @@ Part::Part(Score* s) m_preferSharpFlat = PreferSharpFlat::AUTO; } +//--------------------------------------------------------- +// ~Part +//--------------------------------------------------------- + +Part::~Part() +{ + // Delete all instruments owned by this Part + for (auto it = m_instruments.begin(); it != m_instruments.end(); ++it) { + delete it->second; + } +} + //--------------------------------------------------------- // initFromInstrTemplate //--------------------------------------------------------- @@ -349,6 +361,10 @@ void Part::setInstrument(const Instrument& i, Fraction tick) void Part::setInstruments(const InstrumentList& instruments) { + // Delete all old instruments before clearing + for (auto it = m_instruments.begin(); it != m_instruments.end(); ++it) { + delete it->second; + } m_instruments.clear(); for (auto it = instruments.begin(); it != instruments.end(); ++it) { @@ -367,6 +383,7 @@ void Part::removeInstrument(const Fraction& tick) LOGD("Part::removeInstrument: not found at tick %d", tick.ticks()); return; } + delete i->second; // Delete the instrument before erasing m_instruments.erase(i); } @@ -379,6 +396,7 @@ void Part::removeNonPrimaryInstruments() auto it = m_instruments.begin(); while (it != m_instruments.end()) { if (it->first != -1) { + delete it->second; // Delete the instrument before erasing it = m_instruments.erase(it); continue; } diff --git a/src/engraving/dom/part.h b/src/engraving/dom/part.h index c87d7de45b020..5d70f83947e31 100644 --- a/src/engraving/dom/part.h +++ b/src/engraving/dom/part.h @@ -67,6 +67,7 @@ class Part final : public EngravingObject static const int DEFAULT_COLOR = 0x3399ff; Part(Score* score = nullptr); + ~Part(); void initFromInstrTemplate(const InstrumentTemplate*); const muse::ID& id() const; diff --git a/src/engraving/editing/editinstrumentchange.cpp b/src/engraving/editing/editinstrumentchange.cpp index 5d346e202333c..d42b5292c2286 100644 --- a/src/engraving/editing/editinstrumentchange.cpp +++ b/src/engraving/editing/editinstrumentchange.cpp @@ -55,3 +55,19 @@ void ChangeInstrument::flip(EditData*) // remember original instrument instrument = oi; } + +//--------------------------------------------------------- +// ChangeInstrument::cleanup +//--------------------------------------------------------- + +void ChangeInstrument::cleanup(bool undo) +{ + // Delete the instrument pointer that is not currently in use + // After undo/redo, one of the instruments is no longer referenced + // The 'instrument' member holds the "other" instrument after flip + // We need to delete it when the undo command is being cleaned up + if (instrument) { + delete instrument; + instrument = nullptr; + } +} diff --git a/src/engraving/editing/editinstrumentchange.h b/src/engraving/editing/editinstrumentchange.h index 7bc42baa23c3e..559531c004c1c 100644 --- a/src/engraving/editing/editinstrumentchange.h +++ b/src/engraving/editing/editinstrumentchange.h @@ -36,6 +36,7 @@ class ChangeInstrument : public UndoCommand Instrument* instrument = nullptr; void flip(EditData*) override; + void cleanup(bool undo) override; public: ChangeInstrument(InstrumentChange* _is, Instrument* i)