Arthur Schwarz <aschwarz1309@xxxxxxx> writes: > I ran the compiler from the shell (g++ -pedantic main.cpp) without any errors or > warnings and with the same results. I don't think that the method 'new' is in > error. The segmentation fault does not occur unless the virtual function, fnc, > is uncommented. If 'fnc' is commented, 'new' executes correctly. I think that > this might be a compiler bug, but before I waste anyone's time I thought I'd get > validation that I'm not doing some dumb ol' thing. The bug is in your program, as g++-4.7 -Wall warns: main.cpp: In static member function ‘static void* baseClass::operator new(size_t)’: main.cpp:7:76: warning: no return statement in function returning non-void [-Wreturn-type] If you fix that, e.g. by adding "return ::operator new(size);", then the program will not crash even if you uncomment the virtual functions. With the buggy baseClass::operator new, why does it matter whether the classes have virtual functions? It's because GCC implements virtual functions by adding a vtable pointer to each instance of the class. The constructors of baseClass and inheritClass then initialize the vtable pointer. Because baseClass::operator new returned something bogus, the "this" pointer is bogus in these constructors, and they write to some memory location where they shouldn't. Judging from the assembly code generated by GCC, it seems likely that the "this" pointer points to the std::cout object, which then becomes corrupted and causes the program to crash. If you comment out the virtual functions, then there is no vtable pointer that the constructors would have to initialize. Because your constructors don't initialize any data members either, they don't write to the baseClass or inheritClass object that is being constructed at the bogus address, thus avoiding the crash. It would surely be unwise to rely on such behaviour though. You can get a similar crash even without virtual functions: =============================================================================== #include <iostream> using namespace std; class baseClass { public: /* buggy code for demonstration purposes */ static void* operator new(size_t size) { cout << "new" << endl << flush;} int x; baseClass() { x = 1; cout << "baseClass constructor" << endl << flush;} }; int main() { new baseClass(); return 0; } =============================================================================== Here, if you remove the x = 1 assignment, it avoids the memory corruption and the crash, although operator new still won't be right.
Attachment:
pgpkzHpm0jIhI.pgp
Description: PGP signature