Skip to content

Commit 7104250

Browse files
fix: Use TKey::ReadObject<T> instead of ReadObj
TKey::ReadObj returns an owning pointer. Using dynamic_cast and ignoring the "not castable" case can leak memory. Also one std::unique_ptr See: https://root-forum.cern.ch/t/possible-leak-with-dynamic-cast-and-tkey-readobj/56799 See: root-project/root#13931
1 parent 8ca8005 commit 7104250

File tree

5 files changed

+48
-62
lines changed

5 files changed

+48
-62
lines changed

examples/simulation/Tutorial4/macros/run_tutorial4_createParameterFile.C

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
/********************************************************************************
2-
* Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
2+
* Copyright (C) 2014-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
33
* *
44
* This software is distributed under the terms of the *
55
* GNU Lesser General Public Licence (LGPL) version 3, *
66
* copied verbatim in the file "LICENSE" *
77
********************************************************************************/
88

9+
#include <TCollection.h>
10+
#include <TGeoManager.h>
11+
#include <TKey.h>
12+
#include <TList.h>
13+
914
// forward declaration
1015
void writeVectorToFile(std::vector<Double_t>& vec, ofstream* myfile);
1116

1217
void run_tutorial4_createParameterFile()
1318
{
14-
1519
// Create shift in x, y, z when true
1620
Bool_t ShiftX = kTRUE;
1721
Bool_t ShiftY = kTRUE;
@@ -42,14 +46,14 @@ void run_tutorial4_createParameterFile()
4246

4347
TList* l = f->GetListOfKeys();
4448

45-
TKey* key;
46-
TIter next(l);
47-
4849
TGeoManager* geoMan{nullptr};
4950

50-
while ((key = (TKey*)next())) {
51-
if (key->ReadObj()->InheritsFrom("TGeoManager")) {
52-
geoMan = static_cast<TGeoManager*>(key->ReadObj());
51+
for (auto key : TRangeDynCast<TKey>(l)) {
52+
if (!key) {
53+
continue;
54+
}
55+
geoMan = key->ReadObject<TGeoManager>();
56+
if (geoMan) {
5357
break;
5458
}
5559
}

fairroot/base/sim/FairModule.cxx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <cstdlib> // for getenv
4646
#include <cstring> // for strcmp, strlen
4747
#include <map>
48+
#include <memory>
4849

4950
void FairModule::ConstructGeometry()
5051
{
@@ -301,9 +302,8 @@ void FairModule::ConstructRootGeometry(TGeoMatrix* shiftM)
301302
*/
302303
TGeoManager* OldGeo = gGeoManager;
303304
TGeoManager* NewGeo = 0;
304-
TGeoVolume* volume = 0;
305-
;
306-
TFile* f = TFile::Open(GetGeometryFileName().Data());
305+
306+
std::unique_ptr<TFile> f{TFile::Open(GetGeometryFileName().Data())};
307307
TList* l = f->GetListOfKeys();
308308
TKey* key;
309309
TIter next(l);
@@ -313,19 +313,19 @@ void FairModule::ConstructRootGeometry(TGeoMatrix* shiftM)
313313
/**loop inside the delivered root file and try to fine a TGeoManager object
314314
* the first TGeoManager found will be read
315315
*/
316-
if (strcmp(key->GetClassName(), "TGeoManager") != 0) {
316+
NewGeo = key->ReadObject<TGeoManager>();
317+
if (!NewGeo) {
317318
continue;
318319
}
319320
gGeoManager = 0;
320-
NewGeo = static_cast<TGeoManager*>(key->ReadObj());
321321
break;
322322
}
323323
if (NewGeo != 0) {
324324
/** in case a TGeoManager was found get the top most volume and the node
325325
*/
326326

327327
NewGeo->cd();
328-
volume = static_cast<TGeoVolume*>(NewGeo->GetNode(0)->GetDaughter(0)->GetVolume());
328+
TGeoVolume* volume = NewGeo->GetNode(0)->GetDaughter(0)->GetVolume();
329329
v1 = volume->MakeCopyVolume(volume->GetShape());
330330
// n=NewGeo->GetTopNode();
331331
n = v1->GetNode(0);
@@ -338,8 +338,8 @@ void FairModule::ConstructRootGeometry(TGeoMatrix* shiftM)
338338
*/
339339

340340
key = static_cast<TKey*>(l->At(0)); // Get the first key in the list
341-
volume = dynamic_cast<TGeoVolume*>(key->ReadObj());
342-
if (volume != 0) {
341+
auto volume = key->ReadObject<TGeoVolume>();
342+
if (volume) {
343343
n = volume->GetNode(0);
344344
}
345345
if (n != 0) {
@@ -415,7 +415,6 @@ void FairModule::ConstructRootGeometry(TGeoMatrix* shiftM)
415415
*/
416416
ExpandNode(n);
417417
delete NewGeo;
418-
delete f;
419418
} else {
420419
LOG(fatal) << "Could not find the given mother volume " << fMotherVolumeName.Data()
421420
<< " where the geomanger should be added.";

fairroot/base/steer/FairRunAna.cxx

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#include "FairTrajFilter.h" // for FairTrajFilter
2929
#include "signal.h"
3030

31-
#include <TCollection.h> // for TIter
31+
#include <TCollection.h> // for TRangeDynCast
3232
#include <TDirectory.h> // for TDirectory::TContext
3333
#include <TFile.h> // for TFile
3434
#include <TGeoManager.h> // for gGeoManager, TGeoManager
@@ -144,17 +144,7 @@ void FairRunAna::Init()
144144

145145
// Load Geometry from user file
146146
if (fLoadGeo) {
147-
if (fInputGeoFile != 0) { // First check if the user has a separate Geo file!
148-
TIter next(fInputGeoFile->GetListOfKeys());
149-
TKey* key;
150-
while ((key = dynamic_cast<TKey*>(next()))) {
151-
if (strcmp(key->GetClassName(), "TGeoManager") != 0) {
152-
continue;
153-
}
154-
gGeoManager = dynamic_cast<TGeoManager*>(key->ReadObj());
155-
break;
156-
}
157-
}
147+
SearchForTGeoManagerInGeoFile();
158148
} else {
159149
/*** Get the container that normly has the geometry and all the basic stuff from simulation*/
160150
fRtdb->getContainer("FairGeoParSet");
@@ -180,17 +170,7 @@ void FairRunAna::Init()
180170
} else { // if(fInputFile )
181171
// NO input file but there is a geometry file
182172
if (fLoadGeo) {
183-
if (fInputGeoFile != 0) { // First check if the user has a separate Geo file!
184-
TIter next(fInputGeoFile->GetListOfKeys());
185-
TKey* key;
186-
while ((key = dynamic_cast<TKey*>(next()))) {
187-
if (strcmp(key->GetClassName(), "TGeoManager") != 0) {
188-
continue;
189-
}
190-
gGeoManager = dynamic_cast<TGeoManager*>(key->ReadObj());
191-
break;
192-
}
193-
}
173+
SearchForTGeoManagerInGeoFile();
194174
}
195175
}
196176

@@ -643,3 +623,21 @@ void FairRunAna::Fill()
643623
}
644624
}
645625
//_____________________________________________________________________________
626+
627+
void FairRunAna::SearchForTGeoManagerInGeoFile()
628+
{
629+
if (!fInputGeoFile) { // First check if the user has a separate Geo file!
630+
return;
631+
}
632+
for (auto key : TRangeDynCast<TKey>(fInputGeoFile->GetListOfKeys())) {
633+
if (!key) {
634+
continue;
635+
}
636+
auto geo = key->ReadObject<TGeoManager>();
637+
if (!geo) {
638+
continue;
639+
}
640+
gGeoManager = geo;
641+
break;
642+
}
643+
}

fairroot/base/steer/FairRunAna.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ class FairRunAna : public FairRun
142142
*/
143143
void CheckRunIdChanged();
144144

145+
/**
146+
* \brief Internal helper: Search for TGeoManager in fInputGeoFile
147+
*/
148+
void SearchForTGeoManagerInGeoFile();
149+
145150
ClassDefOverride(FairRunAna, 6);
146151
};
147152

fairroot/base/steer/FairRunAnaProof.cxx

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,7 @@ void FairRunAnaProof::Init()
9494
// Load Geometry from user file
9595

9696
if (fLoadGeo) {
97-
if (fInputGeoFile != 0) { // First check if the user has a separate Geo file!
98-
TIter next(fInputGeoFile->GetListOfKeys());
99-
TKey* key;
100-
while ((key = static_cast<TKey*>(next()))) {
101-
if (strcmp(key->GetClassName(), "TGeoManager") != 0) {
102-
continue;
103-
}
104-
gGeoManager = static_cast<TGeoManager*>(key->ReadObj());
105-
break;
106-
}
107-
}
97+
SearchForTGeoManagerInGeoFile();
10898
} else {
10999
// FairGeoParSet* geopar=dynamic_cast<FairGeoParSet*>(fRtdb->getContainer("FairGeoParSet"));
110100
fRtdb->getContainer("FairGeoParSet");
@@ -142,17 +132,7 @@ void FairRunAnaProof::Init()
142132
} else { // if(fInputFile )
143133
// NO input file but there is a geometry file
144134
if (fLoadGeo) {
145-
if (fInputGeoFile != 0) { // First check if the user has a separate Geo file!
146-
TIter next(fInputGeoFile->GetListOfKeys());
147-
TKey* key;
148-
while ((key = static_cast<TKey*>(next()))) {
149-
if (strcmp(key->GetClassName(), "TGeoManager") != 0) {
150-
continue;
151-
}
152-
gGeoManager = static_cast<TGeoManager*>(key->ReadObj());
153-
break;
154-
}
155-
}
135+
SearchForTGeoManagerInGeoFile();
156136
}
157137
}
158138
// Init the Chain ptr

0 commit comments

Comments
 (0)