同一程序每隔一次运行产生不同的输出

时间:2018-04-14 21:27:10

标签: c++

这是我编写的快速和肮脏程序的一部分,用于进行一些统计计算。有时我会给我预期的输出,即:

42 1 1
48 13 14
54 12 26
60 11 37
66 6 43
72 13 56
78 23 79
84 14 93
90 6 99
96 0 99
102 0 99
108 1 100

但有时(大约50%的时间我运行程序)输出的最后一行有所不同,如下所示:

108 2 101

我正在使用Debian 64bit上的gcc 7.3.0进行编译,除了-o

之外没有编译器标志

我知道,程序可以更优雅地编写,但我不知道这种奇怪的行为来自哪里。

#include <iostream> //cout, endl
#include <algorithm> //sort
#include <iomanip> // setw(), setfill(), left, right

using namespace std;

void classes(int, int, int[]);

static int sizeOfData = 0;

int main()
{
    int data[] ={
                    80, 71, 57, 80, 75, 77, 60, 86, 77, 56, 81, 50, 89, 54, 90, 73, 60, 83, 65, 82, 84, 54, 85, 58, 79,
                    57, 88, 68, 76, 78, 74, 85, 75, 65, 76, 58, 91, 50, 87, 48, 93, 54, 86, 53, 78, 52, 83, 60, 87, 49,
                    80, 60, 92, 43, 89, 60, 84, 69, 74, 71, 108, 50, 77, 57, 80, 61, 82, 48, 81, 73, 62, 79, 54, 80, 73,
                    81, 62, 81, 71, 79, 81, 74, 59, 81, 66, 87, 53, 80, 50, 87, 51, 82, 58, 81, 49, 92, 50, 88, 62, 93
                    };

    sizeOfData = sizeof(data)/sizeof(data[0]);
    sort(data, data + sizeOfData);

    classes(42, 6, data);
}

void classes(int start, int step, int data[])
{
    int counter = 0;
    int classCounter = 0;

    const char separator = ' ';
    int tabWidth = 8;

    cout << endl;
    cout << left << setw(tabWidth) << setfill(separator) << "class";
    cout << left << setw(tabWidth) << setfill(separator) << "#";
    cout << left << setw(tabWidth) << setfill(separator) << "# cumulative";
    cout << endl << endl;

    int i = 0;
    while(i < sizeOfData)
    {
        classCounter = 0;
        while(data[i] < start + step)
        {
            classCounter++;
            counter++;
            i++;
        }
        cout << left << setw(tabWidth) << setfill(separator) << start;
        cout << left << setw(tabWidth) << setfill(separator) << classCounter;
        cout << left << setw(tabWidth) << setfill(separator) << counter;
        cout << endl;
        start = start + step;
    }
}

3 个答案:

答案 0 :(得分:5)

您的程序在上一次迭代中有未定义的行为。如果i在最后一次迭代中为99,那么您很乐意在内部循环中增加超出数组的边界,之后data[i]是未定义的行为。

要解决此问题,最简单的方法是检查i在内部条件下是否不大于sizeOfData

while((i < sizeOfData) && (data[i] < start + step))

考虑选择像std::vectorstd::array这样的STL容器是值得的 - 它会简化您对数组大小的处理,并且可以使您的classes函数更通用。

答案 1 :(得分:3)

您不会检查嵌套循环中是否i < sizeOfData。这就是问题所在。它可以超出界限 - 未定义的行为

答案 2 :(得分:1)

i循环中的计数器for超出了您在代码中使用的sizeOfData的边界。请尝试检查i值以避免这种情况。