Hi Volker, I saw a couple of problems with your C++ code that will definitely cause you problems. The first is that you are using "array new" to allocate and initialize memory for your array of "EMModule", but you aren't using the corresponding call to "array delete" in the destructor of "EMCalo". Your destructor should look like this instead: EMCalo::~EMCalo() { delete [] Modules; } You were using "delete Modules;", which the C++ Standard says will result in undefined behavior. An easy way to avoid problems like this (i.e. accidentally mixing your forms of "new", "new []", "delete" and "delete []") is to use the "auto_ptr" and "auto_array_ptr" class templates. I have attached my implementation of an "auto_array_ptr" class template to this e-mail which you may find helpful. I've also attached 3 other small files as well (`Foo.hxx', `Foo.cxx' and `volkner.cxx') which demonstrate how to use an "auto_array_ptr". This will currently only work in compiled code, but Masaharu has recently helped me to get the "auto_ptr" class template to work with interpreted code. Hopefully both "auto_ptr" and "auto_array_ptr" will be fully supported in the next release of ROOT. The second problem is that you were calling "delete" on your ifstream. In your code you have: void EMCalo::ReadCalFile( char* n ) { [snip] ifstream setup( n ); [snip] setup.close(); delete setup; } Since "setup" is not allocated on the heap, you shouldn't be calling "delete" on it (setup's destructor will run when it leaves scope). FYI, whenever I get a segvio from cint, I always compile my code (not linking it, mind you), just to let the compiler catch my errors. Your C++ compiler would have caught the errors that I spotted by eye (there may be others that I didn't catch as well). Once the compiler is happy, my code typically runs just fine in the interpreter. This may not be the ROOT development model we would like (i.e. that of getting our code to work first in the interpreter, and then move it to compiled code for efficiency), but it is a fact of life (for me, anyway). -- Matthew D. Langston SLD, Stanford Linear Accelerator Center langston@SLAC.Stanford.EDU #ifndef EXCEPTIONHELPERS_ARRAY_AUTO_PTR #define EXCEPTIONHELPERS_ARRAY_AUTO_PTR // auto_array_ptr -- inspired by from Scott Meyers, "More Effective // C++", 1st edition, (Addison-Wesley, 1996) // // // Copyright (C) 1998, 1999 Matthew D. Langston <langston@SLAC.Stanford.EDU> // // This file is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at // your option) any later version. // // This file is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this file; if not, write to: // // Free Software Foundation, Inc. // Suite 330 // 59 Temple Place // Boston, MA 02111-1307, USA. // Unfortunately, most compilerss don't support `explicit' yet. #ifndef HAVE_EXPLICIT #define explicit #endif namespace MDL { template< class T > class auto_array_ptr { public: // See Item 5 for a description of "explicit". #ifndef __CINT__ explicit #endif auto_array_ptr( T* p = 0 ); // Unfortunately, most compilerss don't support mwmber // templates yet either. #ifdef HAVE_MEMBER_TEMPLATES // Copy constructor member template (see Item 28): // initialize a new auto_array_ptr with any compatible // auto_array_ptr. template< class U > #ifndef __CINT__ explicit #endif auto_array_ptr( auto_array_ptr< U >& rhs ); #else #ifndef __CINT__ explicit #endif auto_array_ptr( auto_array_ptr< T >& rhs ); #endif ~auto_array_ptr(); #ifdef HAVE_MEMBER_TEMPLATES // Assignment operator member template (see Item 28): assign // from any compatible auto_array_ptr. template< class U > auto_array_ptr< T >& operator=( auto_array_ptr< U >& rhs ); #else auto_array_ptr< T >& operator=( auto_array_ptr< T >& rhs ); #endif T& operator*() const; // see Item 28 T* operator->() const; // see Item 28 // Return value of current dumb pointer. T* get() const; // Relinquish ownership of current dumb pointer and return // its value. T* release(); // Delete owned pointer; assume ownership of p. void reset( T* p = 0 ); static void remove( T*& p ); private: T* pointee; }; }; // Include the template definitions. #include "auto_array_ptr.ixx" #endif // EXCEPTIONHELPERS_AUTO_ARRAY_PTR // -*- Mode: C++ -*- // Copyright (C) 1998, 1999 Matthew D. Langston <langston@SLAC.Stanford.EDU> // // This file is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at // your option) any later version. // // This file is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this file; if not, write to: // // Free Software Foundation, Inc. // Suite 330 // 59 Temple Place // Boston, MA 02111-1307, USA. #ifdef HAVE_CONFIG_H #include <config.h> #endif template< class T > inline MDL::auto_array_ptr< T >::auto_array_ptr( T* p ) : pointee( p ) {} template< class T > #ifdef HAVE_MEMBER_TEMPLATES template< class U > inline MDL::auto_array_ptr< T >::auto_array_ptr( auto_array_ptr< U >& rhs ) #else inline MDL::auto_array_ptr< T >::auto_array_ptr( auto_array_ptr< T >& rhs ) #endif : pointee( rhs.release() ) {} template< class T > inline MDL::auto_array_ptr< T >::~auto_array_ptr() { delete[] pointee; } template< class T > #ifdef HAVE_MEMBER_TEMPLATES template< class U > #endif inline MDL::auto_array_ptr< T >& #ifdef HAVE_MEMBER_TEMPLATES MDL::auto_array_ptr< T >::operator=( auto_array_ptr< U >& rhs ) #else MDL::auto_array_ptr< T >::operator=( auto_array_ptr< T >& rhs ) #endif { if ( this != &rhs ) { reset( rhs.release() ); } return *this; } template< class T > inline T& MDL::auto_array_ptr< T >::operator*() const { return *pointee; } template< class T > inline T* MDL::auto_array_ptr< T >::operator->() const { return pointee; } template< class T > inline T* MDL::auto_array_ptr< T >::get() const { return pointee; } template< class T > inline T* MDL::auto_array_ptr< T >::release() { T* oldPointee = pointee; pointee = 0; return oldPointee; } template< class T > inline void MDL::auto_array_ptr< T >::reset( T* p ) { T oldPointee = pointee; pointee = p; delete[] oldPointee; } template< class T > inline void MDL::auto_array_ptr< T >::remove( T*& p ) { T* tempPointee = p; p = 0; delete[] tempPointee; } #ifndef FOO #define FOO class Foo { public: Foo(); virtual ~Foo(); void Print(); private: static int fTotal; int fn; }; #endif // FOO #include "Foo.hxx" #include <iostream> int Foo::fTotal = 0; Foo::Foo() { fn = fTotal++; } Foo::~Foo() { cout << fn << " leaving scope." << endl; } void Foo::Print() { cout << "Foo: Hello, world." << endl; } #include "Foo.hxx" #include "auto_array_ptr.hxx" using namespace MDL; int main( int argc, char* argv[] ) { auto_array_ptr<Foo> foo_temp( new Foo[ 10 ] ); Foo* foo_array = foo_temp.get(); foo_array[ 3 ].Print(); } // Local variables: // compile-command: "g++ -Wall volkner.cxx Foo.cxx -o volkner" // End:
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:38 MET