From 01ba8c2290ced974bc1364884572d5e782baa10c Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Sat, 15 Dec 2007 16:47:23 +0000
Subject: [PATCH] When reading, do not delete the object being pointed to by a
 pointer when the call to ReadObjectAny returns the object.  This happens when
 a user class has a pointer that is initialized by the default constructor to
 the address of another object (read from the same buffer) but it is not
 marked as transient.

git-svn-id: http://root.cern.ch/svn/root/trunk@21388 27541ba8-7e3a-0410-8455-c3a389f83636
---
 io/src/TBufferFile.cxx | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/io/src/TBufferFile.cxx b/io/src/TBufferFile.cxx
index b9eff5a4a78..20268a7b3c9 100644
--- a/io/src/TBufferFile.cxx
+++ b/io/src/TBufferFile.cxx
@@ -1439,7 +1439,10 @@ void TBufferFile::ReadFastArray(void **start, const TClass *cl, Int_t n,
 
       for (Int_t j=0; j<n; j++){
          //delete the object or collection
-         if (start[j] && TStreamerInfo::CanDelete()
+         void *old = start[j];
+         start[j] = ReadObjectAny(cl);
+         if (old && old!=start[j] && 
+             TStreamerInfo::CanDelete()
              // There are some cases where the user may set up a pointer in the (default)
              // constructor but not mark this pointer as transient.  Sometime the value
              // of this pointer is the address of one of the object with just created
@@ -1450,8 +1453,14 @@ void TBufferFile::ReadFastArray(void **start, const TClass *cl, Int_t n,
              // && !CheckObject(start[j],cl)
              // However this can increase the read time significantly (10% in the case
              // of one TLine pointer in the test/Track and run ./Event 200 0 0 20 30000
-             ) ((TClass*)cl)->Destructor(start[j],kFALSE); // call delete and desctructor
-         start[j] = ReadObjectAny(cl);
+             //
+             // If ReadObjectAny returned the same value as we previous had, this means
+             // that when writing this object (start[j] had already been written and
+             // is indeed pointing to the same object as the object the user set up
+             // in the default constructor).
+             ) {
+            ((TClass*)cl)->Destructor(old,kFALSE); // call delete and desctructor
+         }
       }
 
    } else {	//case //-> in comment
-- 
GitLab