RE: file->Get() corrupts existing class members

From: Philippe Canal <pcanal_at_fnal.gov>
Date: Fri, 29 Jun 2007 12:55:53 -0500


Hi,

The direct cause of the segmentation fault is the fact that (because the fitting engine needs to access them by name) by default there can only be one TF1 with the same name.

So when your second object is loaded, its default constructor is called and this constructor build a new TF1 with the same name and this leads to the deletion of the existing TF1.

To solve the problem you simply needs to deregister the function from the global list. So add (in the default constructor, just after the 'new TF1(...)':

      gROOT->GetListOfFunctions()->Remove(fPotentialFromChargedRing);

Cheers,
Philippe.

PS. Towards the end of the same file, I think that instead of only:

   file = 0;
you meant:

   delete file; file = 0;

-----Original Message-----
From: owner-roottalk_at_pcroot.cern.ch [mailto:owner-roottalk_at_pcroot.cern.ch] On Behalf Of Thomas Corona
Sent: Monday, June 25, 2007 3:54 PM
To: roottalk_at_pcroot.cern.ch
Subject: [ROOT] file->Get() corrupts existing class members

Hello ROOTers,

        I am trying to create a program that inputs parameters and checks them against a file. If the file does not exist or has different parameters, the file is (re)written. Otherwise, data is retrieved from the file. When I retrieve the data from the file, however, I seem to lose a TFunction previously defined in the program.

        More specifically, I am creating as a member of class ElectricField

(which inherits from TObject) an instance of TFunction that is defined by a C-style function, and instantiating it in ElectricField's constructor. I write an instance of ElectricField to a TFile if the file does not exist or if the parameters on file differ from the current version. When I "Get" the instance of ElectricField that is on file to compare it with the instance of ElectricField currently open, however, my TFunction becomes corrupt. This is how I trigger the crash:

$ make
$ AxiSymEMField <--------- this creates the first instance of ElectricField and saves it to file
$ AxiSymEMField <--------- this checks the saved instance of ElectricField against the current one

I have placed on lines 56 and 61 of AxiSymEMField.cc PrintFunction() calls, which simply print the address of the function pointer and then tell the function to print itself. When I run AxiSymEMField the second time, I get this crash (gdb backtraced):

////////////////////////////////////////////////////////////////////

before the file is accessed:
0x39eb670
  fPotentialFromChargedRing : Ndim= 1, Npar= 7, Noper= 0

  Par  0                    p0 = 0
  Par  1                    p1 = 0
  Par  2                    p2 = 0
  Par  3                    p3 = 0
  Par  4                    p4 = 0
  Par  5                    p5 = 0
  Par  6                    p6 = 0

after the file is accessed:
0x39eb670

Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000000 0x00000000 in ?? ()
(gdb) bt
#0 0x00000000 in ?? ()
#1 0x000028ef in ElectroMagneticField::E_ComponentsAreSameAsFile ()
#2 0x00002975 in ElectroMagneticField::Initialize ()
#3 0x00002a66 in main ()

////////////////////////////////////////////////////////////////////

I am running on an intel mac (macbook pro) running OS X 4.9 and ROOT v5.14/00e. Thanks for any assistance you can give me!

-T.J. Corona Received on Fri Jun 29 2007 - 20:04:57 CEST

This archive was generated by hypermail 2.2.0 : Tue Jul 03 2007 - 11:50:01 CEST