Rootcint and nested maps

(If this is not the right place to report this problem, please let me know.)

I’d like to implement a multi-dimensional sparse matrix. The easiest way for me to do this is to use nested STL maps. I also want this matrix to be ROOT-persistent.

The following code compiles just fine in GCC 3.4.6, but causes a segmentation fault in rootcint:

[code] typedef Short_t ID_field_t;

// The information for a single hit:                                                                                                              
typedef struct {
  Storage_t energy;      // The sum of all the energy deposited in this hit.
  Storage_t energytime;  // The sum of energy*time deposited in this hit.
} m_hitInfo_t;

// The organization of the hit information is nested maps.                                                                                        
typedef std::map<Int_t, m_hitInfo_t>         m_timeLevel_t;
typedef std::map<ID_field_t, m_timeLevel_t>  m_lchanLevel_t;
typedef std::map<ID_field_t, m_lchanLevel_t> m_chanLevel_t;
typedef std::map<ID_field_t, m_chanLevel_t>  m_cellLevel_t;
typedef std::map<ID_field_t, m_cellLevel_t>  m_modLevel_t;
typedef std::map<ID_field_t, m_modLevel_t>   m_cartLevel_t;
typedef std::map<ID_field_t, m_cartLevel_t>  m_hits_t;
m_hits_t                                     m_hits;

[/code]

Specifically, the segmentation fault occurs if I include more than three levels of nested maps.

Is this is known bug or limitation in rootcint? Is there a work-around?

Hi,

the reason is the length of the symbol. CINT does not yet allocate all its buffers dynamically, so you get a buffer overflow. But that symbol is a big one; nm says: [code]std::_Rb_tree<int, std::pair<int const, std::map<int, std::map<int, std::map<int, std::map<int, int, std::less, std::allocator<std::pair
<int const, int> > >, std::less, std::allocator<std::pair<int const, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > > > > >,
std::less, std::allocator<std::pair<int const, std::map<int, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > >, std::less, std::allocator<std::pair<int const, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > > > > > > > >, std::less, std::alloca
tor<std::pair<int const, std::map<int, std::map<int, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > >, std::less, std::alloc
ator<std::pair<int const, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > > > > >, std::less, std::allocator<std::pair<int co
nst, std::map<int, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > >, std::less, std::allocator<std::pair<int const, std::map
<int, int, std::less, std::allocator<std::pair<int const, int> > > > > > > > > > > > >, std::_Select1st<std::pair<int const, std::map<int, std::map<int, st
d::map<int, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > >, std::less, std::allocator<std::pair<int const, std::map<int, i
nt, std::less, std::allocator<std::pair<int const, int> > > > > >, std::less, std::allocator<std::pair<int const, std::map<int, std::map<int, int, std
::less, std::allocator<std::pair<int const, int> > >, std::less, std::allocator<std::pair<int const, std::map<int, int, std::less, std::allocator
<std::pair<int const, int> > > > > > > > >, std::less, std::allocator<std::pair<int const, std::map<int, std::map<int, std::map<int, int, std::less, s
td::allocator<std::pair<int const, int> > >, std::less, std::allocator<std::pair<int const, std::map<int, int, std::less, std::allocator<std::pair<int
const, int> > > > > >, std::less, std::allocator<std::pair<int const, std::map<int, std::map<int, int, std::less, std::allocator<std::pair<int const,
int> > >, std::less, std::allocator<std::pair<int const, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > > > > > > > > > > >

, std::less, std::allocator<std::pair<int const, std::map<int, std::map<int, std::map<int, std::map<int, int, std::less, std::allocator<std::pair<
int const, int> > >, std::less, std::allocator<std::pair<int const, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > > > > >,
std::less, std::allocator<std::pair<int const, std::map<int, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > >, std::less<int
, std::allocator<std::pair<int const, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > > > > > > > >, std::less, std::allocat
or<std::pair<int const, std::map<int, std::map<int, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > >, std::less, std::alloca
tor<std::pair<int const, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > > > > >, std::less, std::allocator<std::pair<int con
st, std::map<int, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > >, std::less, std::allocator<std::pair<int const, std::map<
int, int, std::less, std::allocator<std::pair<int const, int> > > > > > > > > > > > > > >::_Rb_tree(std::less const&, std::allocator<std::pair<int con
st, std::map<int, std::map<int, std::map<int, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > >, std::less, std::allocator<st
d::pair<int const, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > > > > >, std::less, std::allocator<std::pair<int const, st
d::map<int, std::map<int, int, std::less, std::allocator<std::pair<int const, int> > >, std::less, std::allocator<std::pair<int const, std::map<int, i
nt, std::less, std::allocator<std::pair<int const, int> > > > > > > > >, std::less, std::allocator<std::pair<int const, std::map<int, std::map<int, st
d::map<int, int, std::less, std::allocator<std::pair<int const, int> > >, std::less, std::allocator<std::pair<int const, std::map<int, int, std::less<
int>, std::allocator<std::pair<int const, int> > > > > >, std::less, std::allocator<std::pair<int const, std::map<int, std::map<int, int, std::less, s
td::allocator<std::pair<int const, int> > >, std::less, std::allocator<std::pair<int const, std::map<int, int, std::less, std::allocator<std::pair<int
const, int> > > > > > > > > > > > > > const&)[/code] which is a challenge for any parser, even for human eyes :slight_smile:

Now the solution is simple: instead of typedef std::map<ID_field_t, m_cellLevel_t> m_modLevel_t;
you “cut” the names by introducing a dummy class:

class m_modLevel_t: public std::map<ID_field_t, m_cellLevel_t> {};

Cheers, Axel.