From 7fc355501275572879424f01fda72af887623c48 Mon Sep 17 00:00:00 2001 From: Zhiwen Zhao Date: Fri, 12 Jun 2026 23:42:19 -0400 Subject: [PATCH] Return the ASCII system stream as unique_ptr to stop a per-load leak gSystemTextFileStream returned a heap-allocated std::ifstream*; callers only close()d it and never delete()d, leaking one std::ifstream per ASCII geometry/material load (and on the not-found / nullptr paths). The leak grows with geometry reloads, so long interactive sessions accumulate it. Return std::unique_ptr so ownership transfers to the caller and the stream is closed and freed on scope exit. The three return IN; sites move the same unique_ptr; return nullptr; constructs an empty one. Callers drop the now-redundant IN->close() (RAII handles it). Fixes #132 Co-Authored-By: Claude Fable 5 --- gemc/gsystem/gsystemFactories/text/loadGeometry.cc | 3 +-- gemc/gsystem/gsystemFactories/text/loadMaterials.cc | 3 +-- gemc/gsystem/gsystemFactories/text/systemTextFactory.cc | 5 +++-- gemc/gsystem/gsystemFactories/text/systemTextFactory.h | 6 +++++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/gemc/gsystem/gsystemFactories/text/loadGeometry.cc b/gemc/gsystem/gsystemFactories/text/loadGeometry.cc index 5fef7e71..6f0a9772 100644 --- a/gemc/gsystem/gsystemFactories/text/loadGeometry.cc +++ b/gemc/gsystem/gsystemFactories/text/loadGeometry.cc @@ -34,7 +34,6 @@ void GSystemTextFactory::loadGeometry(GSystem* system) { gutilities::getStringVectorFromStringWithDelimiter(dbline, "|"); system->addGVolume(gvolumePars); } - - IN->close(); + // IN (unique_ptr) closes the file and frees the stream on scope exit. } } diff --git a/gemc/gsystem/gsystemFactories/text/loadMaterials.cc b/gemc/gsystem/gsystemFactories/text/loadMaterials.cc index 519da168..448f1867 100644 --- a/gemc/gsystem/gsystemFactories/text/loadMaterials.cc +++ b/gemc/gsystem/gsystemFactories/text/loadMaterials.cc @@ -28,7 +28,6 @@ void GSystemTextFactory::loadMaterials(GSystem* system) { gutilities::getStringVectorFromStringWithDelimiter(dbline, "|"); system->addGMaterial(gmaterialsPars); } - - IN->close(); + // IN (unique_ptr) closes the file and frees the stream on scope exit. } } diff --git a/gemc/gsystem/gsystemFactories/text/systemTextFactory.cc b/gemc/gsystem/gsystemFactories/text/systemTextFactory.cc index acf1bf72..95a488a8 100644 --- a/gemc/gsystem/gsystemFactories/text/systemTextFactory.cc +++ b/gemc/gsystem/gsystemFactories/text/systemTextFactory.cc @@ -14,12 +14,13 @@ // cpp #include +#include // returns the file stream, checking all possible directories. // SYSTEMTYPE can be: // - GTEXTGEOMTYPE (mandatory, exit if not found) // - GTEXTMATSTYPE -std::ifstream* GSystemTextFactory::gSystemTextFileStream(GSystem* system, const std::string& SYSTEMTYPE) { +std::unique_ptr GSystemTextFactory::gSystemTextFileStream(GSystem* system, const std::string& SYSTEMTYPE) { std::string fileName = system->getFilePath(); std::string variation = system->getVariation(); std::string fname = fileName + SYSTEMTYPE + variation + ".txt"; @@ -27,7 +28,7 @@ std::ifstream* GSystemTextFactory::gSystemTextFileStream(GSystem* system, const log->info(0, "gSystemTextFileStream filename is: ", fname); // default dir is "." - auto IN = new std::ifstream(fname.c_str()); + auto IN = std::make_unique(fname.c_str()); if (IN->good()) { log->info(1, "Trying file ", fname); diff --git a/gemc/gsystem/gsystemFactories/text/systemTextFactory.h b/gemc/gsystem/gsystemFactories/text/systemTextFactory.h index 184a3b2a..da0e55fa 100644 --- a/gemc/gsystem/gsystemFactories/text/systemTextFactory.h +++ b/gemc/gsystem/gsystemFactories/text/systemTextFactory.h @@ -3,6 +3,10 @@ // gsystem #include +// c++ +#include +#include + // file types #define GTEXTGEOMTYPE "__geometry_" #define GTEXTMATSTYPE "__materials_" @@ -76,5 +80,5 @@ class GSystemTextFactory : public GSystemFactory * - For geometry, failure to locate a file triggers an error unless \c system->getAnnotations() is \c "mats_only". * - For materials, failure to locate a file is treated as "no materials provided". */ - std::ifstream* gSystemTextFileStream(GSystem* system, const std::string& SYSTEMTYPE); + std::unique_ptr gSystemTextFileStream(GSystem* system, const std::string& SYSTEMTYPE); };