Accesing member object/variable question

Hi ROOTers

I am trying to implement a class with the following declarations:

class APIanalyzer : public TGMainFrame {

private:
  TRootEmbeddedCanvas *fEcanvas;
  TGStatusBar *fStatusBar;
  char* myFavouriteText;
  int totalCanvas;

public:
    //Other functions...
APIanalyzer::APIanalyzer(const TGWindow *p,UInt_t w,UInt_t h,int argc, char **argv)
  : TGMainFrame(p,w,h),canvasCounter(0) {

  fEcanvas = new TRootEmbeddedCanvas ("Ecanvas",this,1000,800);


  int parts[]={60,20,20};
  fStatusBar = new TGStatusBar(this,50,10,kHorizontalFrame);
  fStatusBar->SetParts(parts,sizeof(parts)/sizeof(parts[0]));
  this->AddFrame(fStatusBar,new TGLayoutHints(kLHintsBottom | kLHintsLeft | kLHintsExpandX,0,0,2,0));

  fStatusBar->SetText("This works here....",1);


  // Sets window name and shows the main frame
  this->SetWindowName("API Pre-Analysis Plots");
  this->MapSubwindows();
  this->Resize(GetDefaultSize());
  this->MapWindow();
  this->Connect("CloseWindow()", "APIanalyzer", this, "DoExit()");
  this->DontCallClose();
  
   ProcessData();
}


    void GetCoordinates(){

          //status bar has been divided into three parts
         fStatusBar->SetText("My test",0);
          fStatusBar->SetText(myFavouriteText,2);
    }

   void ProcessData(){

        TCanvas *c = fEcanvas->GetCanvas();
         c->Divide(1,totalCanvas);

        for(int i=0;i<totalCanvas;i++){
             TPad* p1=(TPad *)(c->cd(i+1));
            gPad->AddExec("dynamic",
                        Form("((APIanalyzer*)0x%x)->GetCoordinates()",this));
       }
   }

int main(int argc, char **argv){
  
  TApplication theApp("APIanalyzer", &argc, argv);
  APIanalyzer mainWindow(gClient->GetRoot(),600,500,theApp.Argc(), theApp.Argv());

  //APIanalyzer subWindow(gClient->GetRoot(),600,500,theApp.Argc(), theApp.Argv());
  theApp.Run();
  return 0;
}

As you see, I am assigning a member function of APIanalyzer to each pad in the canvas via gPad->AddExec(). Now I get the following error:

[quote]
*** Break *** segmentation violation
Attaching to program: /proc/30876/exe, process 30876
[Thread debugging using libthread_db enabled]
[New Thread 0x7f80cb1516f0 (LWP 30876)]
done.
0x00007f80c53ee4a5 in waitpid () from /lib/libc.so.6
error detected on stdin
The program is running. Quit anyway (and detach it)? (y or n) [answered Y; input not from terminal]
Detaching from program: /proc/30876/exe, process 30876[/quote]

The error happens because I am trying accessing the fStatusBar object after I have done the linkage of GetCoordinates() function to each pad. In general, I find out that if I defined the following inside my get coordinates, I also get a segmentation fault:

It seems that I do not have access to my member variables/objects/functions. Is there a way I could get over this problem? I am thinking maybe the best way to go around this problem is by defining signals and slots. I am still curious to know If I could make my code work by rewriting it in another way (maybe a proper way?).

Thank you,
Kris

Hi,

what you describe is a typical symptom of a wrong object address, e.g. because the pointer to the object APIanalyzer is NULL, or because it is not initialized or its value is corrupted. E.g. you should use 0x%lx as format string; the address might not fit into an int.

Cheers, Axel.

[quote=“Axel”]Hi,

what you describe is a typical symptom of a wrong object address, e.g. because the pointer to the object APIanalyzer is NULL, or because it is not initialized or its value is corrupted. E.g. you should use 0x%lx as format string; the address might not fit into an int.

Cheers, Axel.[/quote]

Axel,
In your post, do you refer to (?):

gPad->AddExec("dynamic", Form("((APIanalyzer*)0x%x)->GetCoordinates()",this));

I test this part of the code and it works fine. I agree that the problem is a wrong object address. I am not a programmer but I am making an assumption of what my problem could be. The problem seems to be accessing member objects dynamically from the member function GetCoordinates() after I had assigned it to each pad.
It seems that each pad has now access to my GetCoordinates function, but GetCoordinates function (being a member function of APIanalyzer) does not have access to other member variabes of APIanalyzer.

Can you see what my problem really is? I might get some small sample code working… the code I type up here in this post was to show the main structure of the program and the problem.

Laters,
Kris

Hi,

yes that was the fragment I was referring to. If correcting that to what I suggest does not help then we’ll need a running example showing the issue.

Cheers, Axel.

Here I have attached the basic source code that reproduces my problem. I might be doing something wrong by improperly accessing my objects (?). I will be neat if I could make it work :slight_smile:

Kris
APIbasicSrc.tar (20 KB)

I do not see any problem in running your application. When playing with it, I get, eg

[code]Ploting loaded files…
Normal termination[VME]…

Nasty error here too… 6060


Taken From: my200
Coordinates are: (48.562,100.191)


Nasty error here too… 6060


Taken From: my100
Coordinates are: (63.9295,70.918)


[/code]
Could you clarify which version you use and on which platform?
Did you install from source?

Rene

Never mind my problem. My program did not work in ROOT version 19.04 but it works fine in root 5.24.00.

Thxs for your help…

Kris

Rene,

I was able to run my code without problem in other machines. I tested in v5.24.00 and it seems to work fine and I get about the same results as you do. However on my machine, I cannot get the code to work. I decided to install the latest version v.5.25.02 and I keep having segmentation faults when I try to access member variables/objects from my GetCoordinate() function. I decided to install root v5.24.00 and the problem is still there.

I compile from source. I got the sources from root.cern.ch server via ftp. I compile by using the standards commands:

***First setting the env variables… ROOTSYS, PATH,
./configure
make
make install

The error is a bit different this time:

Any suggestions?
Kris

Some additional info about my machine:

[quote]
Linux bucaramanga.Suffield.drdc-rddc.gc.ca 2.6.26.8-57.fc8 #1 SMP Thu Dec 18 18:59:49 EST 2008 x86_64 x86_64 x86_64 GNU/Linux

bash-3.2$ gcc -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: …/configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)[/quote]

I notice that my program does not fail in 32 bit architecture machines. (Tested it so far in three machines) I will see if I can get another 64bit machine going here.

Kris

Compile ROOT and your application in debug mode, then run under valgrind to see what is happening.

Rene

Just double checking, I will run the following commands

./configure
make -g
make install

Or do I have modify the ROOT’s makefile, DEBUGFLAGS variable?
or maybe I should try -ggdb?

Thanks,
Cristian

write the file MyConfig.mk with the following:

[code]PLATFORM = linux

OPT = -g -O2
[/code]
then
./configure
make
and make install if not in current place

then use valgrind with:

valgrind --tool=memcheck \ --suppressions=$ROOTSYS/etc/valgrind-root.supp \ root.exe
Rene

Hi,

OK, third time: 0x%lx.

Cheers, Axel.

Axel,

I run my program before in different platforms and my problem persisted only on my 64bit machine. Implementing your suggestion in my code did indeed solve the problem. Thank you,

Cristian

Hi Cristian,

glad to hear that it works :slight_smile:

Cheers, Axel.