程序到目前为止计算
ASCII代码中每个字符的出现次数,昨天测试时,它运行良好,即使在我尝试过的最大的情况下也没有错误(小说Huck Finn)。我今天加载了它并再次测试了它,它给了我一个分段错误。我没有更改或添加任何代码。它与昨天完美运行的代码相同。我不明白它今天会如何工作,而不是第二天。运行调试器时,我得到这个:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7343f01 in getc () from /lib64/libc.so.6
我的代码:
#include <cstdio>
using namespace std;
//==============================================================
// initialize
//==============================================================
// initialize(freq) initializes all values in the array pointed
// to by freq to 0.
//==============================================================
void initialize(int* freq)
{
for(int i = 0; i<=256; i++)
{
freq[i]=0;
}
}
//==============================================================
// getFreq
//==============================================================
// getFreq(inf, freq) counts the number of occurences of each
// character in file inf and stores those numbers into the array
// freq at with the index number being the ASCII code for that
// character
//==============================================================
void getFreq(FILE* inf, int* freq)
{
int c = fgetc(inf);
while(c != EOF)
{
freq[c]++;
c = fgetc(inf);
}
}
//==============================================================
// showCount
//==============================================================
// showCount(freq) prints the counts of the characters stored in
// freq at with the indexs being the ASCII code for each charater.
// *Does not print characters that do not occur
//==============================================================
void showCount(int* freq)
{
for(int i = 0; i <= 256; i++)
{
if(freq[i]> 0)
{
if(i == ' ')
{
printf("Spaces: %i n", freq[i]);
}
else if(i == 'n')
{
printf("Newlines: %i n", freq[i]);
}
else if(i == 't')
{
printf("Tabs: %i n", freq[i]);
}
else if(i == '.')
{
printf("Periods: %i n", freq[i]);
}
else
{
printf("%c's: %i n",i , freq[i]);
}
}
}
}
int main(int argc, char* argv[])
{
int* freq = new int[256];
initialize(freq);
FILE* inf = fopen(argv[1], "r");
getFreq(inf, freq);
showCount(freq);
fclose(inf);
}
当数组实际上只有 256 个从索引 0 到索引 255 的元素时,您在代码中无处不在地使用 i<=256。代码表现出未定义的行为。昨天工作正常,今天咬我的屁股是一个完美的例子,说明当代码展示 UB 时会发生什么。
您不会通过访问数组外部的元素(从 0-255 的数组的索引 256)来检查 fopen
的返回值和溢出缓冲区。