TClonesArray with TClonesArray

Dear ROOT’ers
I have problem with TClonesArray that have object with TClonesArray, usually I want to add event to my array of TClonesArray by

UEvent *uevent = new ((*fEvents[i])[j]) UEvent(*(UEvent*)fCurrentEvent));

later when I have few UEvents in my TClonessArray[i], I do something with them, and later I clean them by:

fEvents[i]->Clear("C")

In my UEvent class Clear(“C”) is called and looking as :

fParticles->Clear();//fParticles is TClonesArray 

The last method called fEvents->Clear() but when I run over more analysis the size of RAM taken by my application is growing. This mean that the memory is still allocated in new place.
I’m doing something wrong, I don’t want to call delete and clear those tables each time, because this require CPU time. I red the post when people have simmilar problem but if I understood Clear(“C”) solved the problem.
UEvent.cxx (5.53 KB)

Can you, please, provide us with a complete and simple code sample instead of this incomplete definition to reproduce your problem?

Hi,
Thank you for answer, I upload all files (all should be in same directory), I do some test with new function “Rebuild”:

UEvent *uevent = (UEvent*)buffer[0]->ConstructedAt(j); uevent->Rebuild((UEvent*)fCurrentEvent);
This seems to work, but this is not general sollution (in case of unknow objects withou “Rebuild” function) because if I understood manual calling “new Class” should work as well.
UParticle.cxx (7.29 KB)
UParticle.h (4.7 KB)
UEvent.h (2.51 KB)
UEvent.cxx (6 KB)
main_macro.C (140 Bytes)
macro.cxx (702 Bytes)

[quote=“dwielane”]Hi,
Thank you for answer, I upload all files (all should be in same directory), I do some test with new function “Rebuild”:

UEvent *uevent = (UEvent*)buffer[0]->ConstructedAt(j); uevent->Rebuild((UEvent*)fCurrentEvent);
This seems to work, but this is not general sollution (in case of unknow objects withou “Rebuild” function) because if I understood manual calling “new Class” should work as well.[/quote]

I’m sorry, I do not understand what you are trying to do. You create 5000 objects and immediately delete them in a loop iteration and expect every next object to re-use the memory block of the previous object or what?
I see the commented line also (in macro.cxx) - is it the line I need to uncomment to see any problem you suspect? About this line while re-using a memory block in a nested look [0, 5) - do you intentionally create memory leaks? Can you give me, please, the actuall macro.cxx I need?

This CreateRandom, delete is only to simulate the behaviour of reading events form file. I want to read 5000 events, store them i groups of 5 events to do mixing. When I finish mixing e.g. event 1-5, I want to use the same memory (in TClonesArray) to store events 6-10, and so one.
So if you want to see the problem- you need only to remove comment from this line - then yo will see that “clear” seems not working and events 6-10 take new place in RAM instead of replace events 1-5.

I wan’t to use TClones because they should’nt waste time for memory alloc-deallocation.
The rebuild is only temporary sollution that I don’t want to use.

[quote=“dwielane”]This CreateRandom, delete is only to simulate the behaviour of reading events form file. I want to read 5000 events, store them i groups of 5 events to do mixing. When I finish mixing e.g. event 1-5, I want to use the same memory (in TClonesArray) to store events 6-10, and so one.
So if you want to see the problem- you need only to remove comment from this line - then yo will see that “clear” seems not working and events 6-10 take new place in RAM instead of replace events 1-5.

I wan’t to use TClones because they should’nt waste time for memory alloc-deallocation.
The rebuild is only temporary sollution that I don’t want to use.[/quote]

Ok, that’s exactly how I understand your code. When you do new(ptr)Object(parameters) (this is a placement new) you create a new object at address ‘ptr’. It’s clear, that if this memory previously was occupied by some object, you’re doing something bad - you have to destroy the previous object or all the information (pointers to allocated data, etc.) is lost (“overwritten” by the new object). The way to destroy the previous object - is to use ‘pseudo-destructor call’, like ptr->~Object();. But this is not how TClones array should be used.
For ‘Clear’ to work you have to implement this Clear in your class.
For next iteration to work - instead of new(buffer[0][j])Object(parameters) you have to call ConstructedAt(i).
I’ll make an small example for you, if my explanation is not enough. But I’m sure the documentation for TClonesArray explains this pretty well (indeed, it mentions ‘abuses’ and ‘wrong uses’).
P.S. In my cla.C, in principle, I can omit particles_.Clear(“C”); having only nActive_ = 0; but Clear can help in case Particle is more complex and can do some cleanup in its own Clear method.
cla.C (1.98 KB)

Thank you,
I saw this new array[i] on TClonesArray examples as good way to avoid reallocating array. So I thought that this should work for any objects.
So problem is solved, thank you for your help.

It works but you have to understand what you are doing.
Have a look at my macro.
TClonesArray, indeed, designed for (re)use without reallocating - I demonstrated how. If you replace my newEvent = … with newEvent = new (events[j])Event;
you’ll immediately have the memory leak you had in your code and from iteration to iteration the amount of memory used will be constantly growing.