【问题标题】:Segfault when calling a method c++调用方法c ++时的段错误
【发布时间】:2011-02-05 07:47:28
【问题描述】:

我对 c++ 还很陌生,我有点被这个问题难住了。我正在尝试将调用中的变量分配给另一个类中的方法,但它总是出现段错误。我的代码编译时没有任何警告,并且我检查了 gdb 中的所有变量是否正确,但函数调用本身似乎会导致段错误。我使用的代码大致如下:

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 并且值直接返回。但它仍然存在段错误。至于贴出实际代码,比较大,应该贴哪些部分?

【问题讨论】:

  • 我们需要看到真正的代码。
  • local_variable 不是很本地化,是吗? :) 它是一个成员变量。此外,测试 bool 以返回该 bool 有点多余:return local_variable;。当然,您也不需要先存储它:return game_actions_history.test_history(); 无论如何,这段代码“很好”。你可以创建一个Game g;,但你不能调用g.some_function();,它是私有的。如果不是,它会工作得很好。
  • test_history 中还有哪些其他代码?您是否尝试过调试器和/或检查内核以查看堆栈转储?
  • std::cout&lt;&lt;"test"; 可能实际上会被执行,但如果没有换行符,它可能不会刷新到屏幕上。
  • 发布与指针、数组或手动内存实例化/删除有关的任何内容。

标签: c++ methods segmentation-fault call


【解决方案1】:

据我所知,您显示的代码没有任何问题。但是,段错误通常是一个很好的迹象,表明您的内存已损坏。除了您所展示的内容之外,它还发生在其他地方,并且只会影响这里的代码。我会查看您处理数组、指针或任何手动内存交互的任何地方。

【讨论】:

  • 我猜确实是这样。我刚刚制作了一个不包含任何其他函数的代码的简化版本,它似乎可以正常工作。
  • 继续发布一些处理内存和指针的代码。这个论坛是关于帮助的。我怀疑有人会介意你抹掉你现在在那里的东西。我们甚至可以向您展示如何抛出异常而不是段错误。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    代码很好,但示例太不完整,无法说明问题所在。我建议的一些事情:

    为每个类的析构函数和构造函数添加打印输出:

    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 文件没有重新编译,您可能会遇到这种崩溃更改标题后。

    其他一些可能性是:

    • 堆栈溢出:由于深度递归,您已经在堆栈上分配了大量内存,或者正在分配包含大量数据作为局部变量的对象(即未创建或使用 new 或 malloc 的堆))
    • 损坏的类 vtable(通常仅可能由于您的构建工具中的依赖错误),
    • 损坏的对象 vtable 指针:可能通过滥用指针:使用指向已删除内存的指针,或错误地写入正在使用的地址。在您的示例中不太可能,因为没有虚函数。
    • 维护一个指针或对分配在堆栈上已被删除的对象的引用:上面的打印输出代码将揭示这种情况。

    【讨论】:

    • 您在“[] 将打印输出发送到 cout 而不是 cerr”中切换了 cout 和 cerr。是的 cerr (仍然)是无缓冲的,它的优点是你不必乱用 endl。
    【解决方案4】:

    我成功地使用了valgrind 并处理了很多段错误。

    您是否尝试使用由 segfault 引起的 coredump 运行 gdb?来自 man gdb:

    gdb program core
    

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

    ulimit -c unlimited
    

    【讨论】:

    • Valgrind 非常适合我。我以错误的顺序删除对象。
    【解决方案5】:

    我想知道,因为您在 Game 类的私有中定义了 some_function()。所以你上面提到的代码结构也会为此抛出错误。

    【讨论】:

      猜你喜欢
      • 2018-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-07
      • 2016-09-24
      相关资源
      最近更新 更多