Error in <THashList::Delete>: A list is accessing an object (0x47a4ef0) already deleted (list name = THashList)


ROOT Version: 6.24.02
Platform: Alma linux 9.2
Compiler: gcc 11.5.0-5

Dear experts

I got the error message above when opening the ROOT file in a function:

void COMET::IRECBE::ReadResponseFile(std::string const& type){
    std::string SIMDETRESPROOT = getenv("SIMDETECTORRESPONSEROOT");
    std::string responseFile = SIMDETRESPROOT+"/parameters/RECBE_response/"+COMET::IOARuntimeParameters::Get().GetParameterS("SimDetectorResponse.RECBE." + type + "ResponseFunctionFileName")+".root";

    //read TDC response function
    COMETNamedLog("IRECBE", "Loading response file: " << responseFile);
    std::unique_ptr<TFile> f_resp{ TFile::Open(responseFile.c_str(), "READ")};
    if(!f_resp){
        std::string msg = "can not find RECBE " + type + " respone file";
        throw std::runtime_error(msg);
    }
    TIter next(f_resp->GetListOfKeys());
    TKey* key;
    while( (key = (TKey*)next()) ){
        TGraph* g_in = dynamic_cast<TGraph*>(key->ReadObj());
        if(g_in){
            std::string graphName = g_in->GetName();
            if(graphName == "g_deadTime"){
                fTDCDeadTime = std::make_shared<TGraph>(*g_in);
            }
            else{
                int const input = std::stoi(graphName.substr(2));
                std::shared_ptr<TGraph> g = std::make_shared<TGraph>(*g_in);

                if(type == "ADC") fADCResponseFunction[input] = g;
                else if(type == "TDC") fTDCResponseFunction[input] = g;
                else COMETNamedError("IRECBE", "Unknown response type: " << type);
            }
        }
    }
    f_resp->Close();
    COMETNamedInfo("IRECBE", "Finished reading response function");
}

This function will be called twice and type will be different (read different files). When it is called 2nd time I got the error message, many.

Notice that when I directly open the 2nd ROOT file by root file.root (I’m sure that root version is the same) I won’t get any error message. Only when the file is opened in this function I will get error messages. Why?

Do you get this error message at file opening time or later in you code ?

After checking the output I found this error message occur when processing the line:

f_resp->Close();

Only the second time of calling this fuction (ReadResponseFile(std::string const& type)) I get errors.

Do you get the same error if you supress the code in betwen. Something like:

void COMET::IRECBE::ReadResponseFile(std::string const& type){
    std::string SIMDETRESPROOT = getenv("SIMDETECTORRESPONSEROOT");
    std::string responseFile = SIMDETRESPROOT+"/parameters/RECBE_response/"+COMET::IOARuntimeParameters::Get().GetParameterS("SimDetectorResponse.RECBE." + type + "ResponseFunctionFileName")+".root";

    //read TDC response function
    COMETNamedLog("IRECBE", "Loading response file: " << responseFile);
    std::unique_ptr<TFile> f_resp{ TFile::Open(responseFile.c_str(), "READ")};
    if(!f_resp){
        std::string msg = "can not find RECBE " + type + " respone file";
        throw std::runtime_error(msg);
    }

    f_resp->Close();
    COMETNamedInfo("IRECBE", "Finished reading response function");
}

No, error messages disappeared.

So something went wrong in between. Can you identify which piece of code causes the error by reintroducing it step by step until the error appears again? Start with the empty while loop, and so on.

Yes, I did that and found that if I only use

if(graphName == "g_deadTime"){
                fTDCDeadTime = std::make_shared<TGraph>(*g_in);
            }

But comment out the else part, the number of error messages became one. And in my 1st file this if will not be processed, in my 2nd file this if will only be processed once (only 1 TGraph called g_deadtime).

Does this mean something wront with TGraph* g_in = dynamic_cast<TGraph*>(key->ReadObj());? Do I need to delete this pointer?

And if I comment out code inside if(g_in)part, there is no error message anymore, which means if I only use dynamic_cast it doesn’t cause the error

One thing maybe I need to mention: When I created those 2 ROOT files, I used a newer ROOT version v6.32.04, and for the 1st file I set the TFile::k630forwardCompatibility right after TFile::Open(name, “RECREATE”), for the 2nd file I set the TFile::k630forwardCompatibility right before the TFile::Close() instead of right after opening. Will this cause the error messages?

May be @pcanal has some idea about it.

I tried this simple example:

root [0] TFile* f = TFile::Open("file.root", "READ")
(TFile *) 0x1d97a70
root [1] TGraph* g = (TGraph*)gDirectory->Get("g_50")
(TGraph *) 0x2450340
root [2] std::shared_ptr<TGraph> gg = std::make_shared<TGraph>(*g)
(std::shared_ptr<TGraph> &) std::shared_ptr -> 0x308d510
root [3] f->Close()
Error in <THashList::Delete>: A list is accessing an object (0x2f5d6e0) already deleted (list name = THashList)

And error message appeared.

std::cout << g->ClassName() << std::endl;

I tried what you suggested with a file I have. I get:

root [0] TFile* f = TFile::Open("tgraph.root", "READ")
(TFile *) 0x7f965204dd00
root [1] TGraph* g = (TGraph*)gDirectory->Get("g1")
(TGraph *) 0x600002114f00
root [2] std::shared_ptr<TGraph> gg = std::make_shared<TGraph>(*g)
(std::shared_ptr<TGraph> &) std::shared_ptr -> 0x600002d30fd8
root [3] f->Close()
root [4] std::cout << g->ClassName() << std::endl;
TGraph
root [5] 

So I do not see the error. Note I added the line suggested by @Wile_E_Coyote and it gives TGraph

root [0] TFile* f = TFile::Open("RECBE_TDCResponse.root", "READ")
(TFile *) 0x2984870
root [1] TGraph* g = (TGraph*)gDirectory->Get("g_50")
(TGraph *) 0x2fc8640
root [2] std::shared_ptr<TGraph> gg = std::make_shared<TGraph>(*g)
(std::shared_ptr<TGraph> &) std::shared_ptr -> 0x2f27800
root [3] f->Close()
Error in <THashList::Delete>: A list is accessing an object (0x3ab3970) already deleted (list name = THashList)
root [4] std::cout<< g->ClassName() <<std::endl
TGraph
(std::basic_ostream<char, std::char_traits<char> >::__ostream_type &) @0x7f61bda26480
root [5] std::cout<< gg->ClassName() <<std::endl
TGraph
(std::basic_ostream<char, std::char_traits<char> >::__ostream_type &) @0x7f61bda26480
root [6] 

Here is what I got.

After I set the TFile::k630forwardCompatibility right after creating the 2nd ROOT file (then write TGraphs in it) instead of before closing it, this error message disappeared. So it should caused by the compability?

I see you are using ROOT 6.24. Can you tried with a more recent version ? (I tried with master which is ROOT 6.37)

I can use a newer version and it won’t cause the error ——- like I said, it seems a compatibility issue…

1 Like

That is when you should be setting it.

May I also ask that do I need to delete he pointer g_in or key (in the top code block)? It always confuses me about the ownership when I use ROOT classes…