Class derived from RooDataSet: bad_alloc error with ROOT 6.14/08 and not ROOT 6.14/04

Dear experts,

I am experiencing a bad_alloc error which occurs when I source ROOT with LCG 94a and beyond, but not with LCG 94. The version of ROOT in LCG 94 is 6.14/04, and the version in LCG 94a is 6.14/08.

I attach a minimal example to reproduce the problem, using a compiled .so of some source code (I have created two of them, one for each LCG version). To run:

source /cvmfs/sft.cern.ch/lcg/views/LCG_X/x86_64-slc6-gcc7-opt/setup.sh
python test.py X

where X = 94 or 94a.

The test script generates a simple RooDataSet, then reads it into a custom GenericDataSet object. I have also attached the source code for GenericDataSet. Even when I use the default GenericDataSet() constructor passing no arguments, I still get a “std::bad_alloc (C++ exception of type bad_alloc)” error.

I am unable to figure out what causes the bad_alloc error with ROOT 6.14/08 in LCG 94a. Any help to understand the problem would be much appreciated. I have tested under gcc8 and centos7 as well and see the same issue - if you require .so compiled for these architectures, I can provide them.

Cheers,
Donal

P.S. The GenericDataSet class inherits from RooDataSet. I notice that the RooDataSet.cxx code is different in 6.14/04 and 6.14/08, in particular there are edits to memory handling and the introduction of MemPoolForRooSets.h. Perhaps these updates have something to do with it?

_ROOT Version: 6.14/04 and 6.14/08
_Platform: x86_64-slc6-gcc7-opt
_Compiler: cmake

example.zip (609.3 KB)

Hello Donal,

it’s indeed custom memory management. Unfortunately, a few RooFit classes rely on having unique memory addresses (i.e. they cannot be recycled by the operating system when you delete and new a dataset). Therefore, the datasets live in a common memory pool, and this one throws if you allocate with the wrong object size.
Try implementing operator new by calling TObject::operator new, to take your class out of the custom memory management.

The same holds for operator delete.

Hi Stephan,

Thanks for the speedy and very helpful reply. I was able to solve the issue with the following updates:

void* GenericDataSet::operator new (size_t bytes)
{
  return TObject::operator new(bytes);
}

instead of

void* GenericDataSet::operator new (size_t bytes)
{
  return RooDataSet::operator new(bytes);
}

I also added an operator delete command:

void GenericDataSet::operator delete (void* ptr) noexcept {
        free(ptr);
    }

I’m very grateful for the help here, was a tricky one to track down!
Donal

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.