Illegal write error checking memory with valgrind

dear all,

I have a simple data structure defined by the following classes

class myobject : public TObject { public: myobject() : TObject(), fChild("myobject") {fChild.SetOwner(kTRUE);}; virtual ~myobject() {fChild.Delete();}; protected: TClonesArray fChild; ClassDef(myobject, 1); };

class child : public myobject { public: child() : myobject(), fBool(kFALSE) {}; ~child() {}; private: Bool_t fBool; ClassDef(child, 1); };

class parent : public myobject { public: parent() : myobject() {new (fChild[0]) child();}; ~parent() {}; private: ClassDef(parent, 1); };

if I run the following code

int main() { parent p; }

it crashes with glibc error

I checked the memory with valgrind and this is the result

[quote]==30404== Memcheck, a memory error detector.
==30404== Copyright © 2002-2005, and GNU GPL’d, by Julian Seward et al.
==30404== Using LibVEX rev 1575, a library for dynamic binary translation.
==30404== Copyright © 2004-2005, and GNU GPL’d, by OpenWorks LLP.
==30404== Using valgrind-3.1.1, a dynamic binary instrumentation framework.
==30404== Copyright © 2000-2005, and GNU GPL’d, by Julian Seward et al.
==30404== For more details, rerun with: -v
==30404==
==30404== Invalid write of size 1
==30404== at 0x804CC12: child::child() (in /home/preghenella/TEST/test)
==30404== by 0x804CBA9: parent::parent() (in /home/preghenella/TEST/test)
==30404== by 0x804C96F: main (in /home/preghenella/TEST/test)
==30404== Address 0x60AF10C is 0 bytes after a block of size 60 alloc’d
==30404== at 0x4004790: operator new(unsigned) (vg_replace_malloc.c:164)
==30404== by 0x415CE75: TStorage::ObjectAlloc(unsigned) (in /home/alisoft/root/v5-23-02/lib/libCore.so.5.23)
==30404== by 0x419ADA6: TClonesArray::operator (in /home/alisoft/root/v5-23-02/lib/libCore.so.5.23)
==30404== by 0x804CB83: parent::parent() (in /home/preghenella/TEST/test)
==30404== by 0x804C96F: main (in /home/preghenella/TEST/test)
==30404==
==30404== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 54 from 2)
==30404== malloc/free: in use at exit: 1,169,243 bytes in 25,225 blocks.
==30404== malloc/free: 44,131 allocs, 18,906 frees, 2,135,557 bytes allocated.
==30404== For counts of detected errors, rerun with: -v
==30404== searching for pointers to 25,225 not-freed blocks.
==30404== checked 7,394,632 bytes.
==30404==
==30404== LEAK SUMMARY:
==30404== definitely lost: 362 bytes in 7 blocks.
==30404== possibly lost: 90,449 bytes in 2,058 blocks.
==30404== still reachable: 1,078,432 bytes in 23,160 blocks.
==30404== suppressed: 0 bytes in 0 blocks.
==30404== Use --leak-check=full to see details of leaked memory.
[/quote]

there is an invalid write (1 byte, which corresponds to the initialization of the Bool_t member of child class) which seems to occur when creating the object child. If I understand correctly the output of valgrind (let me tell you that I’m not expert with valgrind) in the constructor of child “at 0x804CC12: child::child()” there was an illegal write operation which has written outside the alloc’d memory (off-by-one).

If I remove the Bool_t member of child class no error occurs.

Can someone help me undertanding how to properly deal with that?

thank you,
roberto

ps: all the code needed to build the classes is attached (untar and make)
test.tar (60 KB)

Hi,

The following: myobject() : TObject(), fChild("myobject") ... TClonesArray fChild; .... parent() : myobject() {new (fChild[0]) child();}; ...is ‘illegal’. TClonesArray is not a polymorphic container and can only contains a single type of the object, the type specified at constructor. So to solved your issue use: myobject() : TObject(), fChild("child")

Cheers,
Philippe.

yes. sure. they’ra not the same object.
also using a TObjArray instead of a TClonesArray would do the job correctly.
thank you