TPolyLine3D, TCanvas::Clear and segmentation fault

Hello,

in brief, I’m trying to to

  1. create a TPolyLine3D object
  2. create a TCanvas, a TView and plot the TPolyLine3D object
  3. clear the TCanvas
  4. draw again the TPolyLine3D object and here I get segmentation fault or so.

The full working code is the attachment. There is a bool hist switch to use TH1D instead of TPolyLine3D - to illustrate that this problem disappears when TH1D is used.

It may look very strange what I’m doing. In fact, this is extracted from my monitoring program, where users may (interactively) divide TCanvas into an arbitrary grid of TPads and for each pad select which plot to be displayed. The TPolyLine3D is used to sketch the shape of our detector with the actual track.

Any ideas? Many thanks, Kašpi.
easy.cpp (912 Bytes)

It is not clear what you wanted to achieve with your

c->Clear(""); gPad = c;. Can you explain? Did you want c->cd(); c->Clear(""); ?

[quote=“fine”]It is not clear what you wanted to achieve with your

c->Clear(""); gPad = c;. Can you explain?[/quote]

This was a kind of mimic of a user changing the layout of the canvas. In fact, what I should have done is something like

  1. c->Divide(2, 2)
  2. draw objects to all pads
  3. c->Clear()
  4. c->Divide(3, 1)
  5. redraw (still relevant) objects

But if I replace the line gPad = c; by c->Divide(3, 1); c->cd(3); the program doesn’t crash - however it doesn’t show anything in the canvas!! I wanted to illustrate the most severe failure and that’s why I made that modification.

Moreover, I’m posting now a second example, where it crashes. The layout is not changed, I just draw into one pad a polyline, then a histogram and finally the polyline again. And then it crashes. Please find the code in the attachment.

Thanks, Kašpi.
easy2.cpp (1.01 KB)

It is not clear to me what you want to achieve. When using the option “d” you delete all the objects that are in all the pads, ie a statement like det1->Draw() will become invalid after Clear(“d”), the pointer det1 pointing to a deleted object. May be what you want to do is something like below?

Rene

{
	// create two diffrent objects to be displayed - a polyline and a histogram
	double x[6] = {-14.37, 14.37, +25.53,     0., -25.53, -14.37};
	double y[6] = {-11.11, -11.11,     0., +25.53,     0., -11.11};
	double z[6] = {0, 0, 0, 0, 0, 0};
	TPolyLine3D *det1 = new TPolyLine3D(6, z, x, y);

	TH1D* det2 = new TH1D("det1", "det1", 100, 0, 1);

	// create a canvas with pads
	TCanvas *c = new TCanvas();
	c->Divide(2, 2);

	// 1. user decides to display the polyline in pad 3
	c->cd(1);
	TView *view;
	view = TView::CreateView(1, 0, 0);
	view->SetRange(-10, -35, -21, 50, 35, 35);
	view->SetPerspective();
	det1->Draw();

	// 2. user changes his mind and displays the histogram in pad3
	//c->Clear("d"); // to clear the contents of pads
	c->cd(2);
        gPad->Clear(); // to clear the contents of the current pad
	det2->Draw();

	// 3. users again decides to display the polyline
	//c->Clear("d");
	c->cd(3);
        gPad->Clear();
	det1->Draw();

	printf("OK, finishing\n");
}

Thanks for your answer. I guess a lot of confusion comes from not sufficient documentation of TCanvas::Clear. Here is what I found on web

It tells nothing about what happens to objects in the subpads - whether they are deleted or just disassociated with the pad. You said

[quote=“brun”]When using the option “d” you delete all the objects that are in all the pads, ie a statement like det1->Draw() will become invalid after Clear(“d”), the pointer det1 pointing to a deleted object.
[/quote]
but I’m not really sure with this. Look at the code at attachment. I only changed det1 to be of class TH1D and it works. So either the histogram det1 is not deleted or I’m a really lucky boy (my monitoring program with this code has been extensively used for two years).

Also thanks for your code suggestion, but I want all the objects to be drawn to the same pad (in this simple program it looks silly, but in an interactive application it makes sense though). Hence I tried to replace your c->cd(…) by c->cd(3) and again, the code crashes.

What am I doing wrong?

Thanks, Kašpi.
easy3.cpp (684 Bytes)

OK, I understand your problem now, sorry for being slow ::slight_smile:

When clearing a pad, all low level objects like lines, texts, polylines (that have their bit kCanDelete set in the constructor) are automatically deleted. This does not happen for high level objects lihe THxx, TTree, TGraph, TFxx.
To solve the problem with your TPolyLine3D, just add the following statement after the creation of det1.
det1->ResetBit(kCanDelete);

I agree this type of side-effect should be better documented.

Rene

Yes, that was it! Many thanks,

Kašpi.