C函数根据是否调用printf来改变行为

时间:2010-03-15 13:47:11

标签: c printf heisenbug

我有一个处理某些数据的函数,并找到用最低错误对数据进行分类的阈值。它看起来像这样:

void find_threshold(FeatureVal* fvals, sampledata* data, unsigned int num_samples, double* thresh, double* err, int* pol) {
    //code to calculate minThresh, minErr, minPol omitted
    printf("minThresh: %f, minErr: %f, minPol: %d\n", minThresh, minErr, minPol);
    *thresh = minThresh;
    *err = minErr;
    *pol = minPol;
}

然后在我的测试文件中我有这个:

void test_find_threshold() {
    //code to set up test data omitted
    find_threshold(fvals, sdata, 6, &thresh, &err, &pol);

    printf("Expected 5 got %f\n", thresh);
    assert(eq(thresh, 5.0));
    printf("Expected 1 got %d\n", pol);
    assert(pol == 1);
    printf("Expected 0 got %f\n", err);
    assert(eq(err, 0.0));
}

运行并且测试通过以下输出:

minThresh: 5.000000, minErr: 0.000000, minPol: 1
Expected 5 got 5.000000
Expected 1 got 1
Expected 0 got 0.000000

但是,如果我从find_threshold中删除对printf()的调用,则测试突然失败!注释掉断言以便我可以看到返回的内容,输出是:

Expected 5 got -15.000000
Expected 1 got -1
Expected 0 got 0.333333

我无法理解这一点。

2 个答案:

答案 0 :(得分:6)

printf可以致电malloc。因此,如果你有一些悬空指针,调用printf可以改变这些指向的值。如果您的程序严格符合要求,则在调用printf时不会发现这种差异(正如您所期望的那样)。在最坏情况下,printf中的分配可能会失败,但不会无声地破坏其他变量。

答案 1 :(得分:5)

我怀疑使用valgrind

进行内存访问/分配和测试时遇到了一些问题