cout语句改变程序语义

时间:2014-02-13 01:16:14

标签: c++ c++11 initialization cout

我有一段代码,它是一个类的一部分,其细节希望对回答这个问题并不重要。我不想要解决我的问题,但只是解释,我将要描述的行为如何发生。

    Character operator+(Character c) {
        std::vector<float> resDensity(density);
        float l;
        float dh;
        for (int i = 0; i < domains.size(); i++) {
            for (int j = 0; j < c.domains.size(); j++) {
                l = (domains[i].intersection(c.domains[j])).length();
                //std::cout << l;
                dh = c.density[j] * l / domains[i].length();
                resDensity[i] += dh;
            }
        }
        std::vector<Domain> h(domains);
        return Character(h, resDensity);
    }

您可能已经注意到了注释cout语句。由于我的程序中存在数字错误,我遵循了假值,直到我检测到变量l。所以我将它打印到控制台并发现,这个值正是我需要的值,而且程序运行得很好,而且bug只是消失了。再次对它进行取消注释会导致意外的不当行为。

Character类包含字段domainsdensityvector个...

lengthintersection方法:

    float length() {
        float res;
        for (int i = 0; i < is.size(); i++) {
            res += is[i].b - is[i].a;
        }
        return res;
    }

    Domain intersection(Domain d) {
        std::vector<Interval> hi;
        for (auto i = is.begin(); i != is.end(); i++) {
            for (auto j = d.is.begin(); j != d.is.end(); j++) {
                hi.push_back(i->intersection(*j));
            }
        }
        Domain hhh(hi);
        return hhh;
    }

我使用g++ --std=c++11 ...

编译了代码
g++ --version
g++ (GCC) 4.8.2 20131219 (prerelease)

2 个答案:

答案 0 :(得分:4)

length()函数中,res变量未初始化:

    float res;
    for (int i = 0; i < is.size(); i++) {
        res += is[i].b - is[i].a;   // <-- uses an uninitialized res
    }

答案 1 :(得分:3)

length()如何计算Domainhhh是您要返回的局部变量,因此将创建一个副本。如果length()依赖于未复制的内容,那么您将看到奇怪的行为。如果你只是改变intersection()来返回一个浮点数或者创建一个名为intersectionLength()的另一个方法来返回一个浮点数怎么办?你还得到了heisenbug吗?