为什么printf()在递归函数中显示异常行为?

时间:2014-07-07 08:17:58

标签: c++ recursion printf

我有过多次这种体验:在递归函数中使用printf(),输出是一个随机数。但是,使用fflush(stdout)修复了输出。为什么会这样?例如:

以下代码是段树实现。 rangeQuery()函数返回给定范围内的最大元素

    node rangeQuery(node* tree, int root, int lml, int rml, int u, int v)
    {
        //query [u,v] where all descendants of root are in [lml,rml]

        fflush(stdout);     //<<<<------------------------------HERE
        if (u<=lml && rml<=v)
            return tree[root];

        int m=(lml+rml)/2, lc=root*2, rc=root*2+1;
        tree[root].split(tree,tree[lc],tree[rc]);

        node l,r;

        if (u <= m)
            l = rangeQuery(tree, lc, lml, m, u, v);
        if (v > m)
            r = rangeQuery(tree, rc, m+1, rml, u, v);

        tree[root].merge(tree,tree[lc],tree[rc]);

        node res;
        res.merge(tree, l, r);
        return res;
    }
    int main()
    {
        //....
        int opt,a,b;
        scanf("%d%d%d",&opt,&a,&b);
        a--;
        b--;
        node newNode;
        newNode = rangeQuery(tree, 1, 1<<n, (1<<(n+1))-1, a+(1<<n), b+(1<<n));
        printf("%d",newNode.val);
        //....
    }

完整的代码可以在这里找到:http://ideone.com/cTT0X3

如上所示,从rangeQuery()函数中删除fflush()会产生乱码输出,而使用fflush()会产生正确的输出(3)。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

此:

printf("%d",newNode.val);

缺少终止换行符,因此输出将被缓冲,直到打印下一个换行符,或者调用fflush(stdout);。这可能解释了你所看到的。

答案 1 :(得分:1)

尽管存在各种错误,包括:

  • 在C ++程序文件中使用C变量长度的C ++对象数组;
  • 混合C(scanf)和C ++输入(cin);
  • 使用内部标题<bits/stdc++.h>

错误的主要原因是未初始化的变量:

    node l,r;   // **** here

    if (u <= m)
        l = rangeQuery(tree, lc, lml, m, u, v);
    if (v > m)
        r = rangeQuery(tree, rc, m+1, rml, u, v);

    tree[root].merge(tree,tree[lc],tree[rc]);

    node res;
    res.merge(tree, l, r);

如果其中一个条件不成立,则lr将被取消初始化,这意味着对res.merge的调用具有未定义的行为。

使用node l{},r{};初始化它们会导致您的程序输出3,尽管它可能仍然包含其他错误。