Std::vector<class> needs at least one element?

Dear Rooters,

I have come across a strange phenomenum with a class that is stored in a tree. This class contains a std::vector of another class. It can be stored in a tree without problems. But if I want to read the tree, root crashes if the vector does not have at least one element.

The attached macro shows the problem. To let the program run without problems, just uncomment line 42 of main.cpp.

I have checked this with these two binary downloads of ROOT:
WindowsXP/NT/w2000 with VC++ 9.0, version 5.22/00 (good old tar file)
Windows/NT/w2000 with VC++ 9.0, compiled with debug info, version 5.22/00 (good old tar file).

Is there something I am doing completely wrong? What can I do to make it work, besides adding at least one element to the vector? In my case sometimes the vector is empty.

Thank you,
Lutz
testSTDVector.zip (2.58 KB)

Hi,

There is nothing apparently wrong in your code (it works on macos and linux (after renaming your ‘main’ function). I will have to try it on windows. [Note that the windows debug build is know to have so issue with ACLiC and STL containers but the optimized build should work].

Cheers,
Philippe.

Hi Philippe,

did you already check with the windows version? Both of the Windows Versions (Debug and optimized Build) did produce crashes.

This is the stack trace of the optimized Build:> msvcr90.dll!_crt_debugger_hook(int _Reserved=185218816) Line 65 C msvcr90.dll!_invoke_watson(const wchar_t * pszExpression=0x00000000, const wchar_t * pszFunction=0x00000000, const wchar_t * pszFile=0x00000000, unsigned int nLine=0, unsigned int pReserved=0) Line 230 + 0x7 bytes C++ msvcr90.dll!_invalid_parameter_noinfo() Line 125 + 0xc bytes C++ a_cpp.dll!01fb3d2a() [Frames below may be incorrect and/or missing, no symbols loaded for a_cpp.dll] libRIO.dll!01ad03a6() libTree.dll!01e32eff() libTree.dll!01e25256() libTree.dll!01e28f12() libTree.dll!01e2e652() libTree.dll!01e2e6a8() libTree.dll!01e5b4b4() main_cpp.dll!0af51fcf() main_cpp.dll!0af5331b() main_cpp.dll!0af5261c() libCint.dll!00418e80() msvcr90.dll!free(void * pBlock=0xce7c94be) Line 110 C c5ffffff()
And here is the Stacktrace of the Debug version:> msvcp90d.dll!std::_Debug_message(const wchar_t * message=0x0252db48, const wchar_t * file=0x0252d6d8, unsigned int line=98) Line 24 C++ a_cpp.dll!std::_Vector_const_iterator<B,std::allocator<B> >::operator*() Line 98 + 0x14 bytes C++ a_cpp.dll!std::_Vector_iterator<B,std::allocator<B> >::operator*() Line 340 C++ a_cpp.dll!ROOT::TCollectionProxyInfo::Pushback<std::vector<B,std::allocator<B> > >::resize(void * env=0x034e3348) Line 200 + 0x24 bytes C++ libRIO.dll!TGenCollectionProxy::Method::invoke(void * obj=0x034e3348) Line 202 + 0x1c bytes C++ libRIO.dll!TGenCollectionProxy::Allocate(unsigned int n=0, bool __formal=true) Line 867 C++ libTree.dll!TBranchElement::ReadLeaves(TBuffer & b=) Line 3071 + 0x21 bytes C++ libTree.dll!TBranch::GetEntry(__int64 entry=0, int getall=0) Line 1224 + 0x16 bytes C++ libTree.dll!TBranchElement::GetEntry(__int64 entry=0, int getall=0) Line 1827 + 0x14 bytes C++ libTree.dll!TBranchElement::GetEntry(__int64 entry=0, int getall=0) Line 1842 + 0x1e bytes C++ libTree.dll!TTree::GetEntry(__int64 entry=0, int getall=0) Line 4101 + 0x1e bytes C++ main_cpp.dll!ReadRootFile() Line 65 + 0x1b bytes C++ main_cpp.dll!main(int argc=0, char * * argv=0x01d7e5b4) Line 80 C++ main_cpp.dll!G__main_cpp_ACLiC_dict__0_854(G__value * result7=0x00116154, const char * funcname=0x0320f3f8, G__param * libp=0x001102cc, int hash=0) Line 96 + 0x3b bytes C++ libCint.dll!Cint::G__ExceptionWrapper(int (G__value *, const char *, G__param *, int)* funcp=0x0c042200, G__value * result7=0x00116154, char * funcname=0x0320f3f8, G__param * libp=0x001102cc, int hash=0) Line 381 + 0x15 bytes C++ libCint.dll!G__execute_call(G__value * result7=0x00116154, G__param * libp=0x001102cc, G__ifunc_table_internal * ifunc=0x0320f3f8, int ifn=0) Line 2329 + 0x19 bytes C++ libCint.dll!G__call_cppfunc(G__value * result7=0x00116154, G__param * libp=0x001102cc, G__ifunc_table_internal * ifunc=0x0320f3f8, int ifn=0) Line 2515 + 0x15 bytes C++ libCint.dll!G__interpret_func(G__value * result7=0x00116154, const char * funcname=0x00115d4c, G__param * libp=0x001102cc, int hash=421, G__ifunc_table_internal * p_ifunc=0x0320f3f8, int funcmatch=1, int memfunc_flag=0) Line 5275 + 0x15 bytes C++ libCint.dll!G__getfunction(const char * item=0x001198f8, int * known3=0x0011659c, int memfunc_flag=0) Line 2745 + 0x2d bytes C++ libCint.dll!G__getitem(const char * item=0x001198f8) Line 1896 + 0x16 bytes C++ libCint.dll!G__getexpr(const char * expression=0x0011cfc0) Line 1470 + 0x2b bytes C++ libCint.dll!G__exec_function(char * statement=0x0011cfc0, int * pc=0x0011d40c, int * piout=0x0011d3fc, int * plargestep=0x0011d3dc, G__value * presult=0x0011cf90) Line 601 + 0xd bytes C++ libCint.dll!G__exec_statement(int * mparen=0x0011d804) Line 6984 + 0x1f bytes C++ libCint.dll!G__interpret_func(G__value * result7=0x001250d4, const char * funcname=0x00124ccc, G__param * libp=0x0011f24c, int hash=1310, G__ifunc_table_internal * p_ifunc=0x01c07738, int funcmatch=1, int memfunc_flag=0) Line 6110 + 0x13 bytes C++ libCint.dll!G__getfunction(const char * item=0x00128878, int * known3=0x0012551c, int memfunc_flag=0) Line 2745 + 0x2d bytes C++ libCint.dll!G__getitem(const char * item=0x00128878) Line 1896 + 0x16 bytes C++ libCint.dll!G__getexpr(const char * expression=0x01c69ae0) Line 1470 + 0x2b bytes C++ libCint.dll!G__calc_internal(const char * exprwithspace=0x0012ceec) Line 1061 + 0x10 bytes C++ libCint.dll!G__process_cmd(char * line=0x018507d0, char * prompt=0x0149be1c, int * more=0x0149be14, int * err=0x0012d788, G__value * rslt=0x0012d794) Line 2245 + 0x13 bytes C++ libCore.dll!TCint::ProcessLine(const char * line=0x018507d0, TInterpreter::EErrorCode * error=0x0012ff0c) Line 420 + 0x1f bytes C++ libCore.dll!TCint::ProcessLineSynch(const char * line=0x018507d0, TInterpreter::EErrorCode * error=0x0012ff0c) Line 487 + 0x1a bytes C++ libCore.dll!TApplication::ExecuteFile(const char * file=0x0012dea7, int * error=0x0012ff0c) Line 952 + 0x34 bytes C++ libCore.dll!TApplication::ProcessFile(const char * file=0x0012dea7, int * error=0x0012ff0c) Line 837 + 0xd bytes C++ libCore.dll!TApplication::ProcessLine(const char * line=0x0012dea4, bool sync=false, int * err=0x0012ff0c) Line 810 + 0x1d bytes C++ libRint.dll!TRint::Run(bool retrn=false) Line 368 + 0x1f bytes C++ root.exe!main(int argc=1, char * * argv=0x0184d9a0) Line 29 + 0x14 bytes C++ root.exe!__tmainCRTStartup() Line 582 + 0x19 bytes C root.exe!mainCRTStartup() Line 399 C kernel32.dll!7c816fd7() [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll] libCint.dll!__CT??_R0?AVbad_alloc@std@@@8??0bad_alloc@std@@QAE@ABV01@@Z12() + 0xea2 bytes C++
from looking at the last stack trace one could conclude that the TTree::GetEntry(Int_t) member calls some function that is somehow trying to dereference an iterator that does not exits (because there are no elements in the vector). But this information might be unreliable, because of your statement:

Do you have any idea wether this error is due to a wrong setup of my computer or due to an error in the windows build?

Thank you,
Lutz

PS: What did you have to change in the main function to make it work with linux and macos?

[quote]PS: What did you have to change in the main function to make it work with linux and macos?[/quote]I just changed the name of the function (from ‘main’ to ‘mymain’)

Cheers,
Philippe.

[quote]did you already check with the windows version? Both of the Windows Versions (Debug and optimized Build) did produce crashes. [/quote]Yes and it crashes for me too :frowning:

Philippe.

Hi,

This problem has been fixed in the head of the SVN trunk.

Cheers,
Philippe.

Dear Philippe,

thank you for looking into this.

Best wishes,
Lutz