【问题标题】:Why is the last value in this specific example user input not being taken for my while loop?为什么我的 while 循环没有采用此特定示例用户输入中的最后一个值?
【发布时间】:2022-01-09 13:26:31
【问题描述】:

我遇到了一个错误,在从while 循环接收用户输入后,我的代码不接受最后一个值。这个错误发生在一个特定的例子上,我不知道为什么会这样。

因此,例如,用户输入:

7  
3 1 4 0 0 2 0

输出是:

3140020

但是,使用以下用户输入(这是具体示例):

7  
3 0 1 0 0 2 0

输出应该是:

3010020

但是,输出是:

301002

我根本想不通。下面附上代码:

#include <iostream>
#include <vector>
#include <math.h>
using namespace std;

// Definition for a binary tree node.
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(NULL), right(NULL)  {}
    TreeNode(int x) : val(x), left(NULL), right(NULL)  {}
};

TreeNode* construct_tree(){
    int n;
    cin >> n;
    int curr_inp;
    vector<TreeNode*> vec;
    for (int i = 0; i < n; i++) {
        cin >> curr_inp;
        cout << curr_inp; // **this is the place of bug**
        if (curr_inp != 0) 
            vec.push_back(new TreeNode(curr_inp));
        else 
            vec.push_back(NULL);
    }

    for(int i = 0; i< floor(n/2);i++ )
    {
        vec[i]->left = vec[2*i+1];
        vec[i]->right = vec[2*i+2];
    }
    cout << '\n';
    return vec[0];
}

int main() {
    TreeNode* root = construct_tree();
    return 0;
}

【问题讨论】:

  • StackOveerflow 是一个问答网站,而不是调试服务。您是否尝试过自己在调试器中单步执行代码以查看其行为与您期望的不同之处? How to debug small programs
  • 小问题:通过为x 提供默认值,您的 2 个TreeNode 构造函数可以合并为 1 个。此外,您的代码存在内存泄漏,因为它不是 delete'ing 任何 new'ed TreeNode 对象。
  • @MarzukhAkib 只需将cout &lt;&lt; curr_inp; 更改为cout &lt;&lt; curr_inp&lt;&lt;endl;,您就会看到最后的输出。
  • @MarzukhAkib 不客气。
  • &lt;math.h&gt; -> &lt;cmath&gt;。 “拥有裸指针”(即使用new 创建的指针,如vec.push_back( new TreeNode( ... ) ))是不受欢迎的。实际上,您的程序正在泄漏该内存(可能会在程序完成后通过操作系统的内存保护清理来保存,但您的 program 正在泄漏)。考虑使用smart pointers,而不是自动释放他们的内存。并尝试取消using namespace std;。 ;-)

标签: c++ while-loop tree user-input tree-traversal


【解决方案1】:

您的 construct_tree() 函数在其第二个 for 循环内崩溃。这会阻止写入cout 的最后一个字符的输出,因为cout 输出默认情况下是缓冲的,并且最后一个字符仍在缓冲区中,并且在崩溃发生时尚未刷新到控制台。

cincout 默认是tie()'ed 一起,所以从cin 读取输入将首先隐式刷新cout,但是在第一个@ 之后没有从cin 读取987654331@ 循环的最后一次迭代写入cout

尝试在第一个 for 循环完成后,在进入第二个 for 循环之前添加对 cout &lt;&lt; flushcout.flush() 的调用。或者在第一个 for 循环内使用 cout &lt;&lt; curr_inp &lt;&lt; flush;。然后你会看到显示的最后一个字符。

然后,您需要修复崩溃。

【讨论】:

  • 非常感谢,添加 cout.flush() 后它确实有效 但是,为什么其他示例输入没有发生此错误,但特别是此示例输入?
  • 这就是调试的目的。显然,您的第二个for 循环有一个逻辑错误,仅针对某些输入而不是其他输入。调试代码是您的工作,而不是我们的工作。
【解决方案2】:

问题不在cout &lt;&lt; curr_inp; 问题在您使用的循环中

    for(int i = 0; i< floor(n/2);i++ )
    {
        vec[i]->left = vec[2*i+1];
        vec[i]->right = vec[2*i+2];
    }

您正在尝试使用空向量调用 leftright

添加空检查后没有分段错误

    for(int i = 0; i< floor(n/2);i++ )
    {
        if (vec[i]) {
            vec[i]->left = vec[2*i+1];
            vec[i]->right = vec[2*i+2];
        } else {
            cout << "nullptr \n";
        }
    }

现在当我使用

7
3 0 1 0 0 2 0

我得到了以下输出

7
3 0 1 0 0 2 0
3010020nullptr 

结论:我不知道你的逻辑是什么,但问题是因为取消引用nullptr

【讨论】:

  • 这对我来说是一件非常不负责任的事情,哎呀。不过谢谢
  • 接受的答案有一个向上箭头,如果你觉得答案有用,可以点击它
猜你喜欢
  • 2021-03-20
  • 2020-11-09
  • 2021-08-20
  • 1970-01-01
  • 1970-01-01
  • 2022-12-04
  • 2018-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多