Re: Just another SEGV ...

From: Marco van Leeuwen (mvl@nikhef.nl)
Date: Tue Aug 17 1999 - 10:14:56 MEST


Hi,

I'm not really an expert on this kind of things, but I've had some
experiences like you, so I'll just have a go at  it... (By the way I've
also read your next mail, but I think the problem is somewhere here.) 

As far as I can tell, you want to make a (arbitrary size) array of EMModule
objects. In my experience, a possible way to go about it, is using an array
of pointers to object (instances). This works fine when using the TObjArray
class, but probably you can also implement something alike by yourself.

At 03:39 PM 8/16/99 +0200, you wrote:
>Hi,
>
>again, I had a problem with a segmentation violation:
>
>Assuming the class EMModule from my previous mails, I introduced the
>following class:
>
>[...]
>
>class EMCalo {
> private:
>  EMModule *Modules;

I don't known whether this is correct. Formally, you want to have a
EMModule**, I think. If this doesn't work, you can try a general pointer:
void* .

NOTE: Char_t* seems to mean an arbitrary size character array, but it
really is a pointer to a character. Generally, you should use the following
code:

Char_t *MyString;
MyString = new Char_t[len];

Which is (almost) equivalent to:
Char_t MyString[len];

>  
> public:
>  EMCalo(int modnum = 1000);
>  ~EMCalo();
>  void ReadCalFile(char* n);
>};
>
>[...]
>
>EMCalo::EMCalo(int modnum) {
>  Modules = new EMModule[modnum];

I think that what you're doing here doesn't work, since the
Interpreter/compiler doesn't know which arguments it should use in the
constructor calls of each EMModule.

So let's try to make this an array of pointers:

Modules = new *EMModule[modnum];


>}
>
>EMCalo::~EMCalo() {
>  delete Modules;
>}
>
>void EMCalo::ReadCalFile(char *n) {
>  Int_t		Rn, Mn, Nn;
>  Float_t	x,y,z,size;
>  
>  ifstream setup(n);
>  while (!setup.eof()) {
>    setup >> Rn;
>    setup >> Mn;
>    setup >> x >> y >> z >> size;
>    cout << Rn << " " << Mn << " "
>         << x  << " " << y  << " " 
>	 << z  << " " << size << endl;    
>
>    Nn = 60*Rn + Mn;
>    Modules[Nn] = EMModule(x,y,z,size);

Since Modules[Nn] are pointers, do:
Modules[Nn] = new EMModule(x,y,z,size);

>  }
>  setup.close();
>  delete setup;      
>}
>	 
>In root, the following happens:
>
>root [2] EMCalo *test = new EMCalo(1000);
>root [3] test->ReadCalFile("current_setup.par");
>1 1 -11.8659 59.6538 226.993 12.2465
>1 2 -33.7912 50.572 226.993 12.2465
>
> *** Break *** segmentation violation
>Root >
>root [4] test->ReadCalFile("current_setup.par");
>1 1 -11.8659 59.6538 226.993 12.2465
>1 2 -33.7912 50.572 226.993 12.2465
>1 3 -50.572 33.7912 226.993 12.2465
>1 4 -59.6538 11.8659 226.993 12.2465
>...
>13 58 60.7391 226.681 12.2989 12.2465
>13 59 36.7117 231.789 12.2989 12.2465
>13 60 12.2821 234.356 12.2989 12.2465
>13 60 12.2821 234.356 12.2989 12.2465
>root [5]
>
>That means, that the file could be read successfully the second
>(and third, ...) time, but not during the first call. After that,
>reloading of macros is no longer possible.

This can be a result of the complicated way ROOT/CINT handles pointers and
tries to fix (trivial?) mistakes in their use.

There are of course also other possible solutions to you question/problem.
You might use a fixed size array of pointers or consider using a linked
list of EMModules. Whatever suits you best...

Hope this helps,

Marco van Leeuwen.



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:38 MET