views:

186

answers:

5

I am fairly new to c++ and I am a bit stumped by this problem. I am trying to assign a variable from a call to a method in another class but it always segfaults. My code compiles with no warnings and I have checked that all variables are correct in gdb but the function call itself seems to cause a segfault. The code I am using is roughly like the following:

class History{
 public:
 bool test_history();
};
bool History::test_history(){
    std::cout<<"test"; //this line never gets executed
    //more code goes in here
    return true;
}


class Game{
 private:
    bool some_function();
 public:
    History game_actions_history;

};


bool Game::some_function(){

  return game_actions_history.test_history();

}

Any tips or advice is greatly appreciated!

EDIT: I edited the code so there is no more local_variable and the value returns directly. But it still segfaults. As for posting the actual code, it's fairly large, what parts should I post?

+1  A: 

From what I can see there's nothing wrong with the code you've displayed. However, segfaults often are a good indication that you've got corrupted memory. It's happening some place else besides what you've shown and only happens to impact the code here. I'd look any place you're dealing with arrays, pointers, or any manual memory interactions.

wheaties
I'm guessing that this is exactly the case. I just made a simplified version of my code that didn't contain any other functions and it appeared to work without any problems.
shuttle87
go ahead and post some of the code where you're dealing with memory stuff and pointers. this forum is about helping. I doubt anyone would mind if you erased what you have up there now. We might even be able to show you how you can throw an exception instead of a segfault.
wheaties
+1  A: 

Shot in the dark. (Game*)this is NULL ?

Matthieu M.
A: 

You mentioned that you've left a bit of code out. I would need to see all of the code in question before I could answer this question.

SethCoder
A: 

The code is fine but the example is too incomplete to say what's wrong. Some things I'd suggest:

Add printouts to each class's destructor and constructor:

Game::Game()               { cerr << this << " Game::Game" << endl; }
Game::Game(Game const&)    { cerr << this << " Game::Game(Game const&)" << endl; }
Game::~Game()              { cerr << this << " Game::~Game" << endl; }
bool Game::some_function() { cerr << this << " Game::some_function()" << endl; ... }

This will reveal:

  • Null object pointers.
  • Bad/deleted class pointers.

Second, for debugging, I'd strongly recommended sending printouts to cerr instead of cout. cout is usually buffered (for efficiency) before being output, cerr is not (at least, this used to be the case). If your program quits without executing its error handlers, at_exit, etc..., you are more likely to see the output if it is unbuffered and printed immediately.

Thirdly, if your class declarations live in a header, the class definitions, live in one cpp file and the code that uses the class in yet another, you may get this kind of crash if either of the cpp files were not recompiled after you changed the header.

Some other possibilities are:

  • stack overflow: you've allocated a lot of memory on the stack because of deep recursion or are allocating objects containing large arrays of data as local variables (i.e. not created or the heap with new or malloc))
  • corrupted class vtable (usually only possible due to dependency errors in your build tools),
  • corrupted object vtable pointer: possible through misuse of pointers: using pointers to deleted memory, or incorrectly writing to an in-use address. Not likely in your example because there are no virtual functions.
  • maintaining a pointer or reference to an object allocated on the stack that has been deleted: the printout code above will uncover this case.
you switched around cout and cerr in "[] sending printouts to cout instead of cerr". And yes cerr is (still) unbuffered, which has the advantage that you don't have to mess around with endl.
NomeN
Thanks. Fixed it.
A: 

I have used valgrind succesfully with a lot of segfaults.

and have you tried to run gdb with the coredump caused by the segfault? from man gdb:

gdb program core

To create a coredump you might have to set:

ulimit -c unlimited
NomeN