这是我编写的快速和肮脏程序的一部分,用于进行一些统计计算。有时我会给我预期的输出,即:
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;
}
}
答案 0 :(得分:5)
您的程序在上一次迭代中有未定义的行为。如果i
在最后一次迭代中为99,那么您很乐意在内部循环中增加超出数组的边界,之后data[i]
是未定义的行为。
要解决此问题,最简单的方法是检查i
在内部条件下是否不大于sizeOfData
。
while((i < sizeOfData) && (data[i] < start + step))
考虑选择像std::vector
或std::array
这样的STL容器是值得的 - 它会简化您对数组大小的处理,并且可以使您的classes
函数更通用。
答案 1 :(得分:3)
您不会检查嵌套循环中是否i < sizeOfData
。这就是问题所在。它可以超出界限 - 未定义的行为。
答案 2 :(得分:1)
i
循环中的计数器for
超出了您在代码中使用的sizeOfData
的边界。请尝试检查i
值以避免这种情况。