【问题标题】:Weird segmentation fault errors奇怪的分段错误
【发布时间】:2010-11-13 20:56:10
【问题描述】:

好的,所以我正在处理一项任务,对于我的一生,我无法弄清楚为什么我会遇到这些分段错误。我仍在学习c++,一般编程,所以我希望比我更聪明的人能帮助我。该程序是一个自组织的二叉搜索树,直到现在我对它并没有太大的困难。这是我用来测试我的 BST 类的主程序的开始,我无法更改 mian 程序,因为它是一项作业。

int main() {
string input;

// get a list of integer values
cout << "Enter a list of integer values in one line: ";
getline(cin, input);

cout << "\n**CHECKPOINT 1**\n";

// create a binary search tree
BST<int> bst1(input);


if (!bst1.empty()) {
    cout << "\n**CHECKPOINT 2**\n";
    cout << "Inorder traversal: ";
    bst1.printInOrder();
    cout << "Level order traversal: ";
bst1.printLevelOrder();

我还没有通过 printInOrder() 函数,这是它的代码

template <typename T>
void BST<T>::printInOrder(BSTNode* t) const
{
    if (t->left != NULL)
        printInOrder(t->left);
    std::cout << " " << t->data << " ";
    if (t->right != NULL)
        printInOrder(t->right); 
}

如果我在 printInOrder 函数的第一行添加一个快速 cout

cout << "Inorder traversal: ";

它还将开始打印树中的一些数字,然后最终再次给我一个分段错误。 :/

所以,如果有人能向我解释 WTF 正在进行,我将不胜感激。一个简单的 cout 行的添加或减去不应该改变这样的事情吗?另外,我觉得有更好的调试方法,如果有人有他们用来解决这个问题的技术,请分享:)提前谢谢!

编辑:我已经尝试过调试器 GDB,但我无法弄清楚,但我又不是很精通调试器的高级功能,所以我可能错过了一些东西。 甚至可以运行的唯一其他函数是从字符串输入构建的构造函数。从调试器中我可以看出,构造函数似乎工作正常,但这里是代码

template <typename T>
BST<T>::BST(const std::string input, int th)
{
    threshold = th;
    root = NULL;        
    T v;
    // Make Input String Stream for easy use of >> operator
    std::istringstream iss (input);
    do
    {
        iss >> v;
        insert(v, root);
    }while(iss.good());
}

EDIT2:

这是我的插入功能的代码,谢谢大家的帮助! :)

template <typename T>
void BST<T>::insert(const T& v, BSTNode *&t)
{
    if(t == NULL)
        {
            t = new BSTNode;
            t->left = NULL;
            t->right = NULL;
            t->data = v;
            t->searchCount = 0;
        }
    else if( v < t->data )
        insert(v, t->left);
    else
        insert(v, t->right);
}

【问题讨论】:

  • 您是否尝试过使用调试器查看崩溃的位置?
  • 如果你使用调试输出,也许使用std::cerr,因为它不会像std::cout那样被缓冲
  • 我认为我们需要更多的代码,...也许问题出在输入上...但是如果没有更多的代码,它真的无法分辨...
  • 在这种情况下,添加一行cout 代码可能会导致更多代码看似运行。 cout 被缓冲,这意味着您的程序实际上不会输出任何内容,直到输出缓冲区已满。当您插入另一个cout 时,您会填充缓冲区并出现之前的cout 文本。之前的cout 行总是被执行,但由于缓冲区未满,文本永远不会进入控制台,直到您添加另一个cout 行。使用cerr 进行调试。
  • 你能也显示 BST::insert() 的代码吗?

标签: c++ segmentation-fault binary-tree


【解决方案1】:

您的输出中明显缺少换行符。通常,行缓冲意味着在遇到换行符之前您什么都看不到。

我会将 PrintOnOrder 之后的行修改为:-

    cout << "\nLevel order traversal: ";

【讨论】:

  • 换行符不一定用转义的换行符 IIRC 刷新缓冲区。但是,使用 std::endl 会刷新缓冲区。
【解决方案2】:

在构造函数中,您将v 插入到树中,即使使用iss &gt;&gt; v 读取数据失败。可能你更想要这样的东西:

while (iss >> v) {
   insert(v, root);
}

但可能导致分段错误的真正原因在于insert(),例如,如果该函数只是将一个指向它接收到的(堆栈分配的)参数的指针插入到树中。参数变量将在函数结束时超出范围(因此不再存在)。如果您只是将指向该变量的指针存储到树中,则该指针将不再指向任何有用的东西。

【讨论】:

  • 不幸的是,更改这些行似乎并没有解决问题:/
【解决方案3】:

我在这里没有发现任何问题。正如其他人指出的那样,输出缓冲可能意味着您的代码实际上成功完成了 printInOrder(),然后在某个地方崩溃了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多