Question about Classes in TClonesArray

Dear ROOTers,
I have a problem with a Class that is stored in a TClonesArray. The class contains a buffer that is resized when necessary. But when I clear the array what does happen to the buffer if the class is added to the TClonesArray again?

To clearify my question please look the following code: The class looks like this:
.h file:[code]class MyArchive;
class A: public TObject
{
public:
A():
fData(0),
fDataLength(0),
fDataSizeBuffer(0) {}

~A()						{delete fData;}

public:
void ReadFromFile(MyArchive &ar);
void Clear(Option_t* = “”) {}

private:
long fDataLength; //length of Data
long fDataSizeBuffer; //!length of the buffer Containing the Data
char *fData; //[fDataLength] the Trace

ClassDef(A,1)				//a A

};[/code].cpp file: [code]#include “A.h”
#include "MyArchive.h"
ClassImp(A)

void A::ReadFromFile(MyArchive &ar)
{
//–read the puls properties from archive–//
ar >> fDataLength;
//–increase the size of the buffer, if necessary–//
if(fDataLength > fDataSizeBuffer)
{
delete [] fData;
fData = new char[fDataLength+5024];
fDataSizeBuffer = fDataLength+5024;
}
//–read data array into the buffer given by data–//
ar.readArray(fData, fDataLength);
}[/code]
The code that generates the TClonesArray (fA):

new (fA[fA.GetEntries()]) A(); And later, when all A are loaded and worked on, I clear the TClonesArray using:

As you can see, in the Clear(…) Member the buffer (fData) doesn’t get deleted, as it should only get deleted when the class is destroyed. If I would delete the buffer in the Clear(…) Member, it would contradict what I want to do, which is to avoid new/delete calls for every iteration.

As far as I understand the placement new, that created the entries of the TClonesArray, it always calls the Constructor of the class. In my case this will lead to a memory leak, because the initialisation of class A will initialize fData to 0, thus not pointing to the buffer anymore. Is this right? If so, how can I go around this problem?

Thank you,
Lutz

Hi Lutz,

You can use the following pattern:for each event { fA.Clear("C"); if (know_number_of_A_for_event) { fA.ExpandCreateFast(number_of_A_for_event); } for each A object { if (! know_number_of_A_for_event) { fA.ExpandCreateFast(fA.GetEntries()+1); } A *ptr = (A*)fA[fA.GetEntries()]; ptr->Init(....); } } where A::Init should reset to the default value all the relevant data member (i.e not the member related to the allocation of fData).
TClonesArray::ExpandCreateFast will call the default constructor of the class A exactly once for each ‘slot’.

Cheers,
Philippe.