Unitialised variable

While running with Valgrind on GEANT 4.16.p01 I have a lot of messages like the one at the end. They all point to an uninitialized variable in the array created here

==215== by 0x1131C4E1: G4Material::AddMaterial(G4Material*, double) (G4Material.cc:487)

I have inspected the code and I do not believe it is a user error. I also do not think that there is something really intrinsically wrong with the code of GEANT4, although someone more familiar with this code should have a serious look. In any case, and to stay on the safe side, one could use a little known feature of C++03 to initialise a whole new array to 0. The git diff is the following

diff --git a/source/materials/src/G4Material.cc b/source/materials/src/G4Material.cc
index 5e2db45…2cc6d8d 100644
— a/source/materials/src/G4Material.cc
+++ b/source/materials/src/G4Material.cc
@@ -484,7 +484,7 @@ void G4Material::AddMaterial(G4Material* material, G4double fraction)
// initialization
if (fNumberOfComponents == 0) {
fMassFractionVector = new G4double[fArrayLength];
- fAtomsVector = new G4int [fArrayLength];
+ fAtomsVector = new G4int [fArrayLength]();
}

G4int nelm = material->GetNumberOfElements();

Best regards.

==215== Use of uninitialised value of size 8
==215== at 0x4C2F023: __GI_memcpy (vg_replace_strmem.c:1037)
==215== by 0x12A93C88: __printf_fp_l (in /usr/lib64/libc-2.17.so)
==215== by 0x12A92486: vfprintf (in /usr/lib64/libc-2.17.so)
==215== by 0x12ABD098: vsnprintf (in /usr/lib64/libc-2.17.so)
==215== by 0x1201F48E: std::__convert_from_v(__locale_struct* const&, char*, int, char const*, …) (c++locale.h:92)
==215== by 0x1204D581: std::ostreambuf_iterator<char, std::char_traits > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits > >::_M_insert_float(std::ostreambuf_iterator<char, std::char_traits >, std::ios_base&, char, char, double) const (locale_facets.tcc:1005)
==215== by 0x1205BDBD: put (locale_facets.h:2438)
==215== by 0x1205BDBD: std::ostream& std::ostream::_M_insert(double) (ostream.tcc:73)
==215== by 0x11A86EDE: operator<< (ostream:221)
==215== by 0x11A86EDE: operator<<(std::ostream&, G4BestUnit) (G4UnitsTable.cc:580)
==215== by 0x1131A6F9: operator<<(std::ostream&, G4Material const*) (G4Material.cc:744)
==215== by 0x1131AB28: operator<<(std::ostream&, std::vector<G4Material*, std::allocator<G4Material*> >) (G4Material.cc:787)
==215== by 0x422BE8: DetectorConstruction::ConstructGeom3() (DetectorConstruction.cc:816)
==215== by 0xAC29BF5: G4RunManager::InitializeGeometry() (G4RunManager.cc:611)
==215== Uninitialised value was created by a heap allocation
==215== at 0x4C2AB68: operator new[](unsigned long) (vg_replace_malloc.c:433)
==215== by 0x1131C4E1: G4Material::AddMaterial(G4Material*, double) (G4Material.cc:487)
==215== by 0x418422: DetectorConstruction::DefineMaterials() (DetectorConstruction.cc:1671)
==215== by 0x41DAF2: DetectorConstruction::ConstructGeom3() (DetectorConstruction.cc:187)
==215== by 0xAC29BF5: G4RunManager::InitializeGeometry() (G4RunManager.cc:611)
==215== by 0xAC29A79: G4RunManager::Initialize() (G4RunManager.cc:587)
==215== by 0xAC32E78: G4MTRunManager::Initialize() (G4MTRunManager.cc:198)
==215== by 0x412235: main (mtinrtest.cc:259)

Hello Federico,

this code was not changed since long time. Many users add a combination or elements and materials to a new material and no problems are reported. Before making any fix it would be interesting to see your material definition method or part of it in order to reproduce the problem.

Vladimir

To enforce Vladimir, AddMaterial() is used in TestEm1 to mix 2 materials (ArgonButane), in TestEm3 to mix 2 materials and 1 element (Aerogel) , in TestEm5 to mix 1 material and 1 element (ArgonCO2) …

Hello Vladimir,
thanks for your reply. You were right, there were user errors in the code. However there is a dangerous situation that can trick some users (as us :frowning: this time). If you add a material to a material and then add an element by number of atoms, the code fails catastrophically with no warning. It is clearly an user error, you cannot add half by weight and half by number of atoms, but what happens is the following (suppose you declare only two components):

  • The first addition does not reach the total number of components and so the fAtomsVector is not calculated;
  • The second call to AddElement(G4Element *, Int atoms) supposes that the fAtomsVector is already filled and it uses it uninitialized.

Perhaps it would not be a bad idea to check on first entry when adding materials or element to one material whether this is done by weight or number, and complain (and abort) if the next addition is not of the same nature.

Thanks and best regards, Federico