diff --git a/include/FastCaloSim/Core/TFCSBinnedShowerBase.h b/include/FastCaloSim/Core/TFCSBinnedShowerBase.h index bfc333c..92a0374 100644 --- a/include/FastCaloSim/Core/TFCSBinnedShowerBase.h +++ b/include/FastCaloSim/Core/TFCSBinnedShowerBase.h @@ -115,6 +115,15 @@ class TFCSBinnedShowerBase : public TFCSLateralShapeParametrizationHitBase // Delete all pointers that were created in get_event() virtual void delete_event(TFCSSimulationState& simulstate) const = 0; + // Called by TFCSSimulationState::DoAuxInfoCleanup() to free heap-allocated + // aux-info objects. Invoked automatically on simulstate destruction so that + // the BSEventData/BSNHits/BSELayer pointers are never leaked even when no + // subsequent simulate() call cleans them up first. + virtual void CleanAuxInfo(TFCSSimulationState& simulstate) const override + { + delete_event(simulstate); + } + // What should be the average energy per hit in the library float m_default_hit_energy = 4.; // What is the maximum number of hits per voxel (for runtime reasons) diff --git a/include/FastCaloSim/Core/TFCSSimulationState.h b/include/FastCaloSim/Core/TFCSSimulationState.h index f7fab99..88451a6 100644 --- a/include/FastCaloSim/Core/TFCSSimulationState.h +++ b/include/FastCaloSim/Core/TFCSSimulationState.h @@ -26,6 +26,7 @@ class FASTCALOSIM_EXPORT TFCSSimulationState { public: TFCSSimulationState(CLHEP::HepRandomEngine* randomEngine = nullptr); + virtual ~TFCSSimulationState(); CLHEP::HepRandomEngine* randomEngine() { return m_randomEngine; } void setRandomEngine(CLHEP::HepRandomEngine* engine) diff --git a/source/Core/TFCSBinnedShowerBase.cxx b/source/Core/TFCSBinnedShowerBase.cxx index dfc6bae..2caa600 100644 --- a/source/Core/TFCSBinnedShowerBase.cxx +++ b/source/Core/TFCSBinnedShowerBase.cxx @@ -67,6 +67,12 @@ FCSReturnCode TFCSBinnedShowerBase::simulate( // Reset the total energy simulstate.set_E(0); + // Register this object as a cleanup handler so that DoAuxInfoCleanup() + // (called from ~TFCSSimulationState) will invoke CleanAuxInfo() -> + // delete_event() even if no subsequent simulate() call runs first. + // AddAuxInfoCleanup uses a set, so repeated calls are idempotent. + simulstate.AddAuxInfoCleanup(this); + get_event(simulstate, eta_center, phi_center, Einit, reference_layer_index); for (long unsigned int layer_index = 0; layer_index < m_geo->n_layers(); diff --git a/source/Core/TFCSSimulationState.cxx b/source/Core/TFCSSimulationState.cxx index c19be03..c73208f 100644 --- a/source/Core/TFCSSimulationState.cxx +++ b/source/Core/TFCSSimulationState.cxx @@ -21,10 +21,15 @@ TFCSSimulationState::TFCSSimulationState(CLHEP::HepRandomEngine* randomEngine) clear(); } +TFCSSimulationState::~TFCSSimulationState() +{ + DoAuxInfoCleanup(); +} + void TFCSSimulationState::clear() { set_SF(1); - m_Ebin = -1; + m_Etot = 0; m_E.clear(); m_Efrac.clear();