2010-04-07 80 views
1

我对C++相当陌生,而且我被这个问题困扰了一下。我想从另一个类的方法调用一个变量,但它总是segfaults。我的代码编译没有警告,我已经检查过所有变量在gdb中都是正确的,但函数调用本身似乎会导致段错误。我使用的代码大致如下:在调用方法时出现Segfault错误C++

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(); 

} 

任何提示或建议非常感谢!

编辑:我编辑的代码,所以没有更多的local_variable和值直接返回。但它仍然存在段错误。至于发布实际的代码,它相当大,我应该发布哪些部分?

+7

我们需要看到真正的代码。 – 2010-04-07 15:20:01

+1

'local_variable'不是很局部,是吗? :)这是一个成员变量。另外,测试一个bool来返回这个bool有点多余:'return local_variable;'。当然,你并不需要首先存储它:'return game_actions_history.test_history();'无论如何,这段代码是“很好”的。你可以做一个'Game g;'但是你不能调用'g.some_function();',它是私有的。如果不是,它会正常工作。 – GManNickG 2010-04-07 15:20:15

+0

你怎么称呼它? – EFraim 2010-04-07 15:20:51

回答

4

从我所看到的,你显示的代码没有错。但是,段错误通常很好地表明你的内存已损坏。除了你所展示的内容之外,它正在发生一些其他的地方,并且只是碰巧影响了这里的代码。我会看看你处理数组,指针或任何手动内存交互的地方。

+0

我猜这就是这种情况。我只是简化了我的代码,没有包含任何其他功能,它似乎没有任何问题。 – shuttle87 2010-04-07 16:01:52

+0

继续前进并发布一些代码,用于处理内存和指针。这个论坛是关于帮助。我怀疑如果你擦掉了你现在在那里的东西,任何人都会介意。我们甚至可以向您展示如何抛出异常而不是段错误。 – wheaties 2010-04-07 17:24:21

1

在黑暗中拍摄。 (Game*)thisNULL

0

你提到你已经留下了一些代码。 在我能回答这个问题之前,我需要查看所有有问题的代码。

1

代码很好,但是这个例子太不完整,不能说出什么问题。有些事情我会建议:

添加打印到每个类的析构函数和构造函数:

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; ... } 

这将揭示:

  • 空对象指针。
  • 错误/已删除的类指针。

第二,对于调试,我强烈建议将打印输出发送到cerr而不是cout。 cout通常在被输出之前被缓冲(为了效率),cerr不是(至少,这是以前的情况)。如果你的程序退出而没有执行错误处理程序,at_exit等等,你很可能会看到输出,如果它没有被缓冲并立即打印。第三,如果你的类声明存在于一个头文件中,那么这个类定义将存在于一个cpp文件中,并且这个代码会在另一个文件中使用这个类,如果其中任何一个cpp文件都不是这样,你可能会遇到这种崩溃在更改标题后重新编译。

的一些其他可能性包括:

  • 堆栈溢出:你已经分配了大量的内存,因为深递归栈上分配都包含数据与局部变量的大阵列(即不产生或对象与新的或的malloc))
  • 损坏的类虚函数表(通常只能堆因您的构建工具的依赖错误),
  • 损坏的对象虚表指针:可以通过指针的误用:用指针来删除内存,或不正确写入正在使用的地址。在您的示例中不可能,因为没有虚拟功能。
  • 维护一个指针或引用指向已被删除的堆栈上分配的对象:上面的打印代码将揭示这种情况。
+0

您在“[]发送打印输出到cout而不是cerr”时切换了cout和cerr。是的,cerr是(还)没有缓冲的,这有一个好处,就是你不必乱搞endl。 – NomeN 2010-04-07 16:07:16

+0

谢谢。修复。 – user48956 2010-04-07 21:13:38

3

我用valgrind成功地用了很多segfaults。

并且您是否尝试过使用segfault导致的coredump运行gdb?从人GDB:

gdb program core 

要创建一个核心转储,您可能需要设置:

ulimit -c unlimited 
相关问题