noob cannot figure out what is wrong - code crash.

Dear all,

Short story: I’ve had fantastic and great help in this forum before. Now I’m stuck, with a openGL problem and unfortunately, I cannot narrow down the problem. I think I’m not good enough at C++ and I tried to do some polymorphism stuff, which sometimes work and sometimes don’t. I previously asked a bit about my implementation here (you don’t need to read it, just FYI):

http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=308315

I attach a zip-file, I hope/think (at least on linux) it compiles right out of the box (makefile is provided):

http://www.mediafire.com/?1r06gdayat130dk

(just type “make”, - NB: only tested on ubuntu Linux, so MS windows people: now you’re warned).

Here’s what happens:

make
./gears
*** glibc detected *** ./gears: munmap_chunk(): invalid pointer: 0x0000000000ee25e0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x78a96)[0x7fbde5db9a96]
/lib/x86_64-linux-gnu/libc.so.6(fclose+0x155)[0x7fbde5da9715]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSt12__basic_fileIcE5closeEv+0x30)[0x7fbde65efbc0]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSt13basic_filebufIcSt11char_traitsIcEE5closeEv+0xa1)[0x7fbde65f3411]
… etc. etc…

I hope one of you would be so kind to tell me what it is, I’m not understanding with my pointers and class usage (you need to download my zip-file, extract it and type make + ./gears)… I would be grateful for your help/explanation, as I feel kind of stuck right now… :frowning:

Thanks!

Instead of “etc. etc.” tell us what the rest of the stack looks like, the important part that’ll tell where in your app the error occurred.

Looks like there’s something wrong when closing your file, but perhaps it was closed as a result of an error.

Make sure the file opened correctly.

This is probably not an OpenGL question but more of a general programming question.

Use a debugger, step through the code, find an IDE you like and use it and debug with it.

Looks like you are calling gl functions before creating a window … move to top of main


int main(int argc, char** argv)
{
	  // ******* OpenGL starting... *******
	  glutInit(&argc, argv);
	  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	  glutInitWindowSize(winSizeX, winSizeY);
	  glutCreateWindow("Testing...");
	  //-----------------
	  glShadeModel(GL_FLAT);
	  glMatrixMode(GL_MODELVIEW);
	  glLoadIdentity();
	  glEnable(GL_MAP1_VERTEX_3);
	  //-----------------
	  glutDisplayFunc(display);
	  glutReshapeFunc(reshape);
	  glutSpecialFunc(special);
	  glutKeyboardFunc(keyboard);
	  glutTimerFunc(100, timer, 0);

  cout << endl;
  makeLineSep();

...

Once That is done, running gdb debugger gives error


Program received signal SIGSEGV, Segmentation fault.
0x0000000000402d79 in findbox () at helper.cpp:232
232		  d_a = abs( pGC->gearValues.d_a );

Looking further it appears that pGC is 0x0 — ie not defined.


(gdb) print pGC
$1 = (gearClass *) 0x0

You need to fix that error.

I guess it helps if you can compile the code :-). Trust Linux to make everything look like a file problem.

This answer is to dorbie:

Instead of “etc. etc.” tell us what the rest of the stack looks like, the important part that’ll tell where in your app the error occurred.

Ok, in that case: I’ll tell where I think the problem is, and then copy paste the rest instead of the “etc. etc”:

It seems like the program crashes before making use of any glut-stuff, namely I’m positive that: It never constructs gearClassFile::gearClassFile in main.cpp, line 257-268 so I never get below main.cpp line 270++. The class gearClassFile has a constructor, line 188, in gearClass.cpp. The last thing the constructor does, is this:


  callFortranFile(); // line 229 of gearClass.cpp
  cout << "Leaving constructor of: gearClassFile::gearClassFile..." << endl;
  cout << endl; // line 231 of gearClass.cpp
}

I know that callFortranFile is called (line 229), but line 230+231 is never executed above. So let’s step further down into it:


void gearClassFile::callFortranFile() // line 270 of gearClass.cpp
{
  makeLineSep(); // line 272 of gearClass.cpp

  cout << "Writing text file for Fortran tooth profiler..." << endl;

This is executed, ok… Let’s look at the end of this member function:


  saveBezier(N_kontur, &cpp_Kontur_id[0],
  			 &cpp_X[0], &cpp_Y[0],
  			 &dataPosX[0], &dataNegX[0]);
  cout << "Done saveBezier, leaving gearClassFile::callFortranFile()..." << endl;
} // this is line 339 in gearClass.cpp

All of this is executed, which must mean that callFortranFile succeeded - at least it couts the last cout before the “}”… Hmm. So, what now? What should I test?

Based on this, I would say that the program should jump back to the constructor
gearClassFile::gearClassFile (lines 188 - 232, namely the to point where it left, i.e is should now go to line 230+231). But it crashes… Why? I think maybe I have some invalid pointer, but to me, it doesnt make sense that it crashes here… I don’t see any reason to crash here… Probably has to do with my virtual/polymorphism, as this is my first time, trying to do something like this (gearClassFile inherits from “drawableObj”, which is found in helper.cpp/helper.h).

I’m totally lost…

Here’s the “etc. etc”-part, you asked about - (I don’t understand it):


Done saveBezier, leaving gearClassFile::callFortranFile()...
*** glibc detected *** ./gears: munmap_chunk(): invalid pointer: 0x000000000064a5e0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x78a96)[0x7f29a6137a96]
/lib/x86_64-linux-gnu/libc.so.6(fclose+0x155)[0x7f29a6127715]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSt12__basic_fileIcE5closeEv+0x30)[0x7f29a696dbc0]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSt13basic_filebufIcSt11char_traitsIcEE5closeEv+0xa1)[0x7f29a6971411]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZNSt14basic_ifstreamIcSt11char_traitsIcEED1Ev+0x3d)[0x7f29a69719fd]
./gears[0x405a4b]
./gears[0x404fd9]
./gears[0x409d5e]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f29a60e030d]
./gears[0x402499]
======= Memory map: ========
00400000-0040e000 r-xp 00000000 00:16 3563531                            /home/mfjo/Downloads/gear_test/gears
0060d000-0060e000 r--p 0000d000 00:16 3563531                            /home/mfjo/Downloads/gear_test/gears
0060e000-0060f000 rw-p 0000e000 00:16 3563531                            /home/mfjo/Downloads/gear_test/gears
00641000-0068d000 rw-p 00000000 00:00 0                                  [heap]
7f29a2ed7000-7f29a2edc000 r-xp 00000000 08:05 4462103                    /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f29a2edc000-7f29a30db000 ---p 00005000 08:05 4462103                    /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f29a30db000-7f29a30dc000 r--p 00004000 08:05 4462103                    /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f29a30dc000-7f29a30dd000 rw-p 00005000 08:05 4462103                    /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f29a30dd000-7f29a30df000 r-xp 00000000 08:05 4456672                    /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f29a30df000-7f29a32de000 ---p 00002000 08:05 4456672                    /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f29a32de000-7f29a32df000 r--p 00001000 08:05 4456672                    /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f29a32df000-7f29a32e0000 rw-p 00002000 08:05 4456672                    /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f29a32e0000-7f29a32fb000 r-xp 00000000 08:05 4464316                    /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f29a32fb000-7f29a34fa000 ---p 0001b000 08:05 4464316                    /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f29a34fa000-7f29a34fb000 r--p 0001a000 08:05 4464316                    /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f29a34fb000-7f29a34fc000 rw-p 0001b000 08:05 4464316                    /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f29a34fc000-7f29a34fe000 r-xp 00000000 08:05 153333                     /lib/x86_64-linux-gnu/libdl-2.13.so
7f29a34fe000-7f29a36fe000 ---p 00002000 08:05 153333                     /lib/x86_64-linux-gnu/libdl-2.13.so
7f29a36fe000-7f29a36ff000 r--p 00002000 08:05 153333                     /lib/x86_64-linux-gnu/libdl-2.13.so
7f29a36ff000-7f29a3700000 rw-p 00003000 08:05 153333                     /lib/x86_64-linux-gnu/libdl-2.13.so
7f29a3700000-7f29a3707000 r-xp 00000000 08:05 131096                     /lib/x86_64-linux-gnu/librt-2.13.so
7f29a3707000-7f29a3906000 ---p 00007000 08:05 131096                     /lib/x86_64-linux-gnu/librt-2.13.so
7f29a3906000-7f29a3907000 r--p 00006000 08:05 131096                     /lib/x86_64-linux-gnu/librt-2.13.so
7f29a3907000-7f29a3908000 rw-p 00007000 08:05 131096                     /lib/x86_64-linux-gnu/librt-2.13.so
7f29a3908000-7f29a391a000 r-xp 00000000 08:05 4464434                    /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f29a391a000-7f29a3b19000 ---p 00012000 08:05 4464434                    /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f29a3b19000-7f29a3b1a000 r--p 00011000 08:05 4464434                    /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f29a3b1a000-7f29a3b1b000 rw-p 00012000 08:05 4464434                    /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0
7f29a3b1b000-7f29a3c4e000 r-xp 00000000 08:05 4464332                    /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f29a3c4e000-7f29a3e4e000 ---p 00133000 08:05 4464332                    /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f29a3e4e000-7f29a3e4f000 r--p 00133000 08:05 4464332                    /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f29a3e4f000-7f29a3e53000 rw-p 00134000 08:05 4464332                    /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f29a3e53000-7f29a5447000 r-xp 00000000 08:05 4589398                    /usr/lib/nvidia-current-updates/libnvidia-glcore.so.280.13
7f29a5447000-7f29a5646000 ---p 015f4000 08:05 4589398                    /usr/lib/nvidia-current-updates/libnvidia-glcore.so.280.13
7f29a5646000-7f29a5c85000 rwxp 015f3000 08:05 4589398                    /usr/lib/nvidia-current-updates/libnvidia-glcore.so.280.13
7f29a5c85000-7f29a5c9f000 rwxp 00000000 00:00 0 
7f29a5c9f000-7f29a5ca2000 r-xp 00000000 08:05 4590577                    /usr/lib/nvidia-current-updates/tls/libnvidia-tls.so.280.13
7f29a5ca2000-7f29a5ea1000 ---p 00003000 08:05 4590577                    /usr/lib/nvidia-current-updates/tls/libnvidia-tls.so.280.13
7f29a5ea1000-7f29a5ea2000 rw-p 00002000 08:05 4590577                    /usr/lib/nvidia-current-updates/tls/libnvidia-tls.so.280.13
7f29a5ea2000-7f29a5eba000 r-xp 00000000 08:05 153340                     /lib/x86_64-linux-gnu/libpthread-2.13.so
7f29a5eba000-7f29a60b9000 ---p 00018000 08:05 153340                     /lib/x86_64-linux-gnu/libpthread-2.13.so
7f29a60b9000-7f29a60ba000 r--p 00017000 08:05 153340                     /lib/x86_64-linux-gnu/libpthread-2.13.so
7f29a60ba000-7f29a60bb000 rw-p 00018000 08:05 153340                     /lib/x86_64-linux-gnu/libpthread-2.13.so
7f29a60bb000-7f29a60bf000 rw-p 00000000 00:00 0 
7f29a60bf000-7f29a6254000 r-xp 00000000 08:05 153332                     /lib/x86_64-linux-gnu/libc-2.13.so
7f29a6254000-7f29a6453000 ---p 00195000 08:05 153332                     /lib/x86_64-linux-gnu/libc-2.13.so
7f29a6453000-7f29a6457000 r--p 00194000 08:05 153332                     /lib/x86_64-linux-gnu/libc-2.13.so
7f29a6457000-7f29a6458000 rw-p 00198000 08:05 153332                     /lib/x86_64-linux-gnu/libc-2.13.so
7f29a6458000-7f29a645e000 rw-p 00000000 00:00 0 
7f29a645e000-7f29a6473000 r-xp 00000000 08:05 139316                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f29a6473000-7f29a6672000 ---p 00015000 08:05 139316                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f29a6672000-7f29a6673000 r--p 00014000 08:05 139316                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f29a6673000-7f29a6674000 rw-p 00015000 08:05 139316                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f29a6674000-7f29a66f7000 r-xp 00000000 08:05 153342                     /lib/x86_64-linux-gnu/libm-2.13.so
7f29a66f7000-7f29a68f6000 ---p 00083000 08:05 153342                     /lib/x86_64-linux-gnu/libm-2.13.so
7f29a68f6000-7f29a68f7000 r--p 00082000 08:05 153342                     /lib/x86_64-linux-gnu/libm-2.13.so
7f29a68f7000-7f29a68f8000 rw-p 00083000 08:05 153342                     /lib/x86_64-linux-gnu/libm-2.13.so
7f29a68f8000-7f29a69e0000 r-xp 00000000 08:05 4459448                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f29a69e0000-7f29a6be0000 ---p 000e8000 08:05 4459448                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f29a6be0000-7f29a6be8000 r--p 000e8000 08:05 4459448                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f29a6be8000-7f29a6bea000 rw-p 000f0000 08:05 4459448                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7f29a6bea000-7f29a6bff000 rw-p 00000000 00:00 0 
7f29a6bff000-7f29a6c6a000 r-xp 00000000 08:05 4465298                    /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.071100
7f29a6c6a000-7f29a6e69000 ---p 0006b000 08:05 4465298                    /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.071100
7f29a6e69000-7f29a6e6b000 r--p 0006a000 08:05 4465298                    /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.071100
7f29a6e6b000-7f29a6e6c000 rw-p 0006c000 08:05 4465298                    /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.071100
7f29a6e6c000-7f29a6eaa000 r-xp 00000000 08:05 4470684                    /usr/lib/libglut.so.3.9.0
7f29a6eaa000-7f29a70a9000 ---p 0003e000 08:05 4470684                    /usr/lib/libglut.so.3.9.0
7f29a70a9000-7f29a70ad000 r--p 0003d000 08:05 4470684                    /usr/lib/libglut.so.3.9.0
7f29a70ad000-7f29a70b2000 rw-p 00041000 08:05 4470684                    /usr/lib/libglut.so.3.9.0
7f29a70b2000-7f29a7173000 r-xp 00000000 08:05 4590222                    /usr/lib/nvidia-current-updates/libGL.so.280.13
7f29a7173000-7f29a7372000 ---p 000c1000 08:05 4590222                    /usr/lib/nvidia-current-updates/libGL.so.280.13
7f29a7372000-7f29a73ad000 rwxp 000c0000 08:05 4590222                    /usr/lib/nvidia-current-updates/libGL.so.280.13
7f29a73ad000-7f29a73c3000 rwxp 00000000 00:00 0 
7f29a73c3000-7f29a73d2000 r-xp 00000000 08:05 153339                     /lib/x86_64-linux-gnu/ld-2.13.so
7f29a73d2000-7f29a73d3000 -wxp 0000f000 08:05 153339                     /lib/x86_64-linux-gnu/ld-2.13.so
7f29a73d3000-7f29a73e4000 r-xp 00010000 08:05 153339                     /lib/x86_64-linux-gnu/ld-2.13.so
7f29a755b000-7f29a75aa000 rw-p 00000000 00:00 0 
7f29a75e1000-7f29a75e3000 rw-p 00000000 00:00 0 
7f29a75e3000-7f29a75e4000 r--p 00020000 08:05 153339                     /lib/x86_64-linux-gnu/ld-2.13.so
7f29a75e4000-7f29a75e6000 rw-p 00021000 08:05 153339                     /lib/x86_64-linux-gnu/ld-2.13.so
7ffffae02000-7ffffae23000 rw-p 00000000 00:00 0                          [stack]
7ffffafe9000-7ffffafea000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

Looks like there’s something wrong when closing your file, but perhaps it was closed as a result of an error.

Make sure the file opened correctly.

I don’t think this is a problem. It seems to write (Verzahnen.txt) + read correctly from the file (Kontur.dat) and in any case, if it failed with file I/O, I wouldn’t expect such a crash with the message: “*** glibc detected *** ./gears: munmap_chunk(): invalid pointer: 0x000000000064a5e0 ***”. I don’t understand this message “glibc detected… etc.”

Invalid pointer: Probably correct, but I don’t know where (or how to fix)…

This is probably not an OpenGL question but more of a general programming question.

Yes, but if I asked in a general programming forum, people would complain about the use of glut-functions in my code and then they would say I should ask in an openGL forum. Another reason for me to ask here, is that the reason for me to (try to use) polymorphism, is that I want a single global class/place from where I can do this:



void display()
{
  glClear(GL_COLOR_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  //==================
  glPushMatrix();
  glTranslatef(xPos, yPos, 0.0);

  for (int z=0; z<(int) allObjs.pObjs.size(); z++)
	{
	  glPushMatrix();
	  (allObjs.pObjs[z])->updateDisplay(); // <=== NB!!! NICE!
	  glPopMatrix();
	}
  ....
  .... // etc
}

You should perhaps know that in top of my main.cpp, line 14, I have this:


drawableObj allObjs; // must be global! - defined in helper.cpp/helper.h

And the problem I have with my gearClassFile::gearClassFile (constructor, never succeeds) inherits from drawableObj, and I would never do this if it wasn’t for openGL. I save a pointer to my graphics objects into allObjs.pObjs[0] (global) so I have a single place, where I can update my display in my openGL-loop…

So I belive - although there is some “general programming problem” here, it is highly worth asking about advice for it, in an openGL-forum.

I’m sorry if I haven’t explained it good enough… I’ll read followup answers/questions and try to elaborate, my poor explanation… Bottom line is: This crash is really strange, in my mind and I don’t understand why it crashes exactly where it does…

It’s very strange… I don’t even get to that place you are at… I get a crash before you… You seem to get to line 270 in main.cpp, but I get a crash just before finishing to construct (this is from main.cpp, line 258):


  drawableObj *pinion =
        new gearClassFile(... // etc

, i.e. I get to line 268 in main.cpp and then it crashes. Under all circumstances, I think something is wrong in/with “gearClassFile” - in your case the crash just happens after me. Which version of g++ do you use, if I may ask? Here’s my version:


g++ --version
g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1

Besides that, you’re saying that this is wrong:


          // line 230 in helper.cpp
	  pGC = dynamic_cast<gearClass*> (allObjs.pObjs[z]);

allObjs is my global “containter” and pObjs is defined as a pointer to all my “graphics objects”:


// line 14 in main.cpp
drawableObj allObjs; // must be global!


  // line 53 in helper.h
  static vector<drawableObj*> pObjs;


  // line 3 in gearClass.cpp
  extern drawableObj allObjs; // must be global!

Notice where I write to pObjs (constructor of gearClassFile, which is called just before we both see a crash):


gearClassFile::gearClassFile(gearTypes gt, double rSpeed, int z_1,
							 double d_a, double x_1, double beta,
							 double m_n, double rho_aP0,
							 GLfloat x=0, GLfloat y=0, double zR=0)
{
  pObjs.push_back(this); // <----- IS THIS OK?
  ...
}

Based on the above, what is the correct way of doing this (you write that pGC is null)?


          // line 230 in helper.cpp
	  pGC = dynamic_cast<gearClass*> (allObjs.pObjs[z]);

I hope I’m not confusing anyone (except myself, I’m very confused)…

?

Thank you.

huh? I didn’t understand that. Should I trust Linux … look like a file problem? What does that mean?

My version of compiler is same as yours


$ gcc --version
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1

When you say it crashes are you running gdb


<make certain glutinit stuff at top of main>
make
gdb ./gears
run
   Program received signal SIGSEGV, Segmentation fault.
   0x0000000000402d79 in findbox () at helper.cpp:232
   232		  d_a = abs( pGC->gearValues.d_a );

print pGC
   $1 = (gearClass *) 0x0

Why are you doing a dynamic_cast? I think that you are running into a casting problem as seen here.


struct Base { };
struct Derived : Base { };
int main() { 
  Derived d; Base *b = &d;
  dynamic_cast<Derived*>(b); // invalid
}

To see the problem, replace Base with "drawableObj" and derived with "gearClass"

struct drawableObj { };
struct gearClass : drawableObj { };
int main() { 
  gearClass d; drawableObj *b = &d;
  dynamic_cast<gearClass*>(b); // invalid
}

Your code seems to follow this path and may explain why pGC is NULL.

In addition to above post,

since you know for certain that it is a gearClass pointer you can use the static cast and
set in findbox()


pGC = static_cast<gearClass*> (allObjs.pObjs[z]);

Then this gets past the first seg fault, but then in gearClassFile constructor try commenting out line 229 to get past the remaining seg fault


//callFortranFile();

The code now at least compiles and runs … displays 4 dashed concentric circles and a green-red axis marker in the center of the screen.

Looks like the seg fault culprit is in the callFortranFile(). Try looking carefully at callFortranFile() for problems

Hi Marshats,

I really appreciate your help & time, it’s great - thank you so much for that! I have collected a few things/questions:

<make certain glutinit stuff at top of main>

Uh, thank you - works better! Although I didn’t belive I called any gl-stuff before? Can you/someone finger-point exactly what GL-point is used before glutinit? Anyway, it works better like you suggested, thanks!

Looking further it appears that pGC is 0x0 — ie not defined.

Aah, you’re right… And thanks a lot for this great link: http://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast - here’s what I don’t understand:

To see the problem, replace Base with “drawableObj” and derived with “gearClass”


struct drawableObj { };
struct gearClass : drawableObj { };
int main() { 
  gearClass d; drawableObj *b = &d;
  dynamic_cast<gearClass*>(b); // invalid
}

Your code seems to follow this path and may explain why pGC is NULL.

… Except that… I took this example from somewhere and right above from where you took the code, they say:

The following code is not valid, because Base is not polymorphic (doesn’t contain a virtual function):

In my case: Base (=drawableObj) IS polymorphic, because helper.h, lines 36-66 declares this (slightly rewritten here):

class drawableObj
{
 public:
  // data:
  ...
  GLfloat posX;
  GLfloat posY;
  ...

  // this should contain pointers to derived classes
  static vector<drawableObj*> pObjs;

  // constructor
  drawableObj();

  // destructor
  virtual ~drawableObj(); // base *DOES* contain virtual functions

  // member functions
  virtual void updateDisplay(); // base *DOES* contain virtual functions
  ...
};

As I remember it, I think I even took the example with dynamic_cast from a book or the web, where it was/is claimed to work (although my memory could be wrong, my memory is supported by the fact that the reason for getting a null pointer cannot be because: “The following code is not valid, because Base is not polymorphic”, because base is polymorphic in my case, isn’t it?)…

As said I’m new to this polymorphic thing, now I just don’t understand why dynamic_cast returns a null pointer (you’re right about it, I get the same as you now, using your instructions - the static_cast works like you wrote!).

Suppose I add a “wheelClass” later (or a “carClass”, a “rectangleClass” or something else), also deriving from the same base class: “drawableObj”, how would I rewrite this into something general ?:


   for (int z=0; z<(int) allObjs.pObjs.size(); z++)
     {
       pGC = static_cast<gearClass*> (allObjs.pObjs[z]);
       ...
     }

Then I could not write “static_cast<gearClass*>” because maybe that should be:

       pGC = static_cast<wheelClass*> (allObjs.pObjs[z]);
       pGC = static_cast<carClass*> (allObjs.pObjs[z]);
       pGC = static_cast<rectangleClass*> (allObjs.pObjs[z]);

i.e. I’m looking for something general, i.e.:


   for (int z=0; z<(int) allObjs.pObjs.size(); z++)
     {
       pGC = static_cast<whatEverTheProperDerivedTypeIs*> (allObjs.pObjs[z]);
       ...
     }

See what I’m trying to learn? :slight_smile: I hope to succeed with this, very soon :slight_smile:

The code now at least compiles and runs … displays 4 dashed concentric circles and a green-red axis marker in the center of the screen.

Looks like the seg fault culprit is in the callFortranFile(). Try looking carefully at callFortranFile() for problems

Yep, you’re right. Thank you very much! I’ll dig into the “callFortranFile()”-thing and hope to solve it, without having to ask about that here. Now I now where to look, so I think I should be able to work it out in my spare time in the coming 1-2 weeks, at least.

FYI: The 4 dashed concentric circles should show/illustrate a gear and the callFortranFile() should read in the gear-coordinates - the result should be something like: http://tiny.cc/9cnjj - if callFortranFile worked, I think you would have seen the real gear - I think it can rotate by making 2. argument in main.cpp to non-zero (rotation speed):

  drawableObj *pinion =
	new gearClassFile(sun,  // maybe type planet here
		      0.0,      // rotSpeed
        ...

The green-red axis marker in the center of the screen is: red=x-vector, green=y-vector, blue=z-vector (in case I rotate it, I usually put in this coordinate system marker so I know which direction is which).

A comment on your question to the statement:


The following code is not valid, because Base is not polymorphic (doesn't contain a virtual function):

The problem is that you are trying to use a member/variable from gearClass … gearValues.d_a is only in the derived class and not in the base class and that makes gearValues.d_a not polymorphic.

you have to know what the cast is the way your logic is (ie to use specialisation for gearClass like ->gearValues.d_a). One solution is to add a method (iamwhat()) to the base class that tells you what the derived class is and you set the id when ever you construct the derived/gearClass.


   for (int z=0; z<(int) allObjs.pObjs.size(); z++)
     {
       switch(allObjs.pObjs[z].iamwhat())
       {
       case id_wheelClass
         wheelClass* pGC = static_cast<wheelClass*> (allObjs.pObjs[z]);
         ... use all wheelClass methods ok
         break;
       case id_carClass
         carClass* pGC = static_cast<carClass*> (allObjs.pObjs[z]);
         ... use all carClass methods ok
         break;
       case id_rectangleClass
         rectangleClass* pGC = static_cast<rectangleClass*> (allObjs.pObjs[z]);
         ... use all rectangleClass methods ok
         break;
       default: 
         break;
       }
     }

Polymorphism helps if you have common virtual methods from drawableObj between derived classes; wheelClass, carClass, rectangleClass, etc. But you are trying to use a non-virtual specialised function only in gearClass and hence you must know that you are a gearClass to be able to upcast it. If it were a virtual function (common from base) you wouldn’t have to do the cast in the first place.

Earlier I deleted a post I made after someone posted that they’d found some gl context creation problem since it was off topic for OpenGL discussion.

In that post I observed that the file read loop was relying on an automatically invoked ifstream destructor to terminate the while around the getline() for an ifstream object on the stack and then exiting the function which would again destroy the ifstream created on the stack.

But I wasn’t sure about it having only glanced at the code. Anyway since posts are now sniffing around that area of code I’m mentioning it again.

This is no longer an OpenGL question but a more generic coding question.

huh? I didn’t understand that. Should I trust Linux … look like a file problem? What does that mean? [/QUOTE]

Unix et.al. use file i/o for a lot of stuff not intuitively related to files, like device driver communication.

Oh, thanks a lot! I feel I learned a lot and having done this mistake now, I hope I’ll never make it again :slight_smile:

you have to know what the cast is the way your logic is (ie to use specialisation for gearClass like ->gearValues.d_a). One solution is to add a method (iamwhat()) to the base class that tells you what the derived class is and you set the id when ever you construct the derived/gearClass.


   for (int z=0; z<(int) allObjs.pObjs.size(); z++)
     {
       switch(allObjs.pObjs[z].iamwhat())
       {
       case id_wheelClass
         wheelClass* pGC = static_cast<wheelClass*> (allObjs.pObjs[z]);
         ... use all wheelClass methods ok
         break;
       case id_carClass
         carClass* pGC = static_cast<carClass*> (allObjs.pObjs[z]);
         ... use all carClass methods ok
         break;
       case id_rectangleClass
         rectangleClass* pGC = static_cast<rectangleClass*> (allObjs.pObjs[z]);
         ... use all rectangleClass methods ok
         break;
       default: 
         break;
       }
     }

Polymorphism helps if you have common virtual methods from drawableObj between derived classes; wheelClass, carClass, rectangleClass, etc. But you are trying to use a non-virtual specialised function only in gearClass and hence you must know that you are a gearClass to be able to upcast it. If it were a virtual function (common from base) you wouldn’t have to do the cast in the first place.

Makes totally sense - thank you very much for that explanation!

Regarding the rest of my problem(s): I’ll ask in a general C++ forum (if I cannot solve it myself), now I know where the problem is…

Thanks again!

Sorry, forgive me but I’m trying to understand what you’re saying, but I don’t understand it…

Are you saying that you looked in my code and found a problem with file i/o? I don’t understand the stack/automatically invoked ifstream destructor-talk, sorry.

Unix et.al. use file i/o for a lot of stuff not intuitively related to files, like device driver communication.

I also don’t understand what you’re saying with that. You downloaded the code, unzipped it and looked at it, right? Sorry, besides from this and that it’s a general programming issue, I’m not good enough at understanding what you’ve written.

Sorry.