Problem with map<string, UserClass*>

Hi ROOTers,

I have a class with a member map object of the form map<string, UserClass*> which I would like to persistify. The problem is, whenever I do this I either a seg fault/bus error on write or on read:


#7 0x93e18e10 in strlen ()
#8 0x0088022f in TString::TString ()
#9 0x023a683c in TEmulatedMapProxy::WriteMap ()
#10 0x023a71c0 in TEmulatedMapProxy::Streamer ()
#11 0x02399577 in TCollectionStreamer::Streamer ()
#12 0x02399ed5 in TCollectionClassStreamer::Stream ()
#13 0x02397698 in TBufferFile::WriteFastArray ()
#14 0x02480797 in TStreamerInfo::WriteBufferAux<char**> ()
#15 0x023eef7d in TStreamerInfoActions::GenericWriteAction ()
#16 0x02392b19 in TBufferFile::ApplySequence ()
#17 0x02391595 in TBufferFile::WriteClassBuffer ()
#18 0x03ce839d in Analysis::CalibrationDataInterfaceROOT::Streamer ()
#19 0x023d3af3 in TKey::TKey ()
#20 0x023ab50e in TFile::CreateKey ()
#21 0x023a1e16 in TDirectoryFile::WriteTObject ()
#22 0x0085ed72 in TObject::Write ()


#7 0x912a16e1 in __gnu_cxx::__exchange_and_add ()
#8 0x023a5238 in TEmulatedCollectionProxy::Shrink ()
#9 0x023a536f in TEmulatedCollectionProxy::Resize ()
#10 0x023a729a in TEmulatedMapProxy::ReadBuffer ()
#11 0x023973c7 in TBufferFile::ReadFastArray ()
#12 0x023fa905 in TStreamerInfoActions::ReadSTL<&(TStreamerInfoActions::ReadSTLMemberWiseSameClass(TBuffer&, void*, TStreamerInfoActions::TConfiguration const*, short)), &(TStreamerInfoActions::ReadSTLObjectWiseFastArray(TBuffer&, void*, TStreamerInfoActions::TConfiguration const*, short, unsigned int))> ()
#13 0x02392b19 in TBufferFile::ApplySequence ()
#14 0x02393195 in TBufferFile::ReadClassBuffer ()
#15 0x03ce004a in Analysis::CalibrationDataInterfaceROOT::Streamer ()
#16 0x023d1345 in TKey::ReadObj ()
#17 0x04697191 in ProofAna::AddDir ()
#18 0x04697ee6 in ProofAna::Begin ()
#19 0x03853a81 in TTreePlayer::Process ()

Which error occurs is random. I understand use of TEmulatedMapProxy to be symptomatic of a missing dictionary, so I’ve tried lots of possibilities in the LinkDef.h file, knowing that CINT can be picky about the std namespace. None make any difference:

#pragma link C++ class pair<string, UserClass*>+;
#pragma link C++ class pair<std::string, UserClass*>+;
#pragma link C++ class std::pair<string, UserClass*>+;
#pragma link C++ class std::pair<std::string, UserClass*>+;

Same with map and so on. UserClass itself also has a dictionary of course.

If I replace UserClass* with an “official” ROOT class, like TMap*, the errors go away. And if I replace std::string with TString, it also works, which is the solution I’m using now. But there really shouldn’t be a difference, right?


As a side note, I had another run-in with TEmulatedMapProxy, where I had a map of the form map<MyClass, vector > in my TSelector, and while the TSelector worked fine in local mode and on the PROOF cluster, when using PROOF Lite it would crash horribly during “Finalize” while setting the selector data members (why is this necessary or useful?). That error was fixed by adding the

#pragma link C++ class pair<MyClass, vector >+;

to the LinkDef.h file. It seems like this class has problems. At the very least, debugging problems involving it is incredibly frustrating.

[quote]And if I replace std::string with TString, it also works, which is the solution I’m using now. But there really shouldn’t be a difference, right?[/quote]A priori the linkdef fragment that ‘works’ would be:#pragma link C++ class map<string,UserClass*>+;Also make sure you have the dictionary for UserClass :slight_smile:.


Yep, tried that, in every variation I could think of. No difference, same problem.

Well … it should :slight_smile:

Could you send me a complete running example reproducing the problem?