有问题的程序获得候选人姓名和选民选择作为输入,输出是一个或多个获胜者的姓名(以防2个或mre候选人并列(。每当我尝试使用自己的输入时,它都很好,无论是单个赢家还是多个赢家。但check50不同意。当我使用调试器时,它最后会说一些关于分段错误的内容,但我看不出代码中的错误在哪里。
我在理解check50为什么坚持程序不完全正确时遇到了问题。问题所在的代码部分是:
void print_winner(void)
{
int c = 0;
int d[(candidate_count - 1)];
int e = 0;
for (int i = 1; i < candidate_count; i++)
{
if (candidates[c].votes < candidates[i].votes)
{
c = i;
}
else if (candidates[c].votes == candidates[i].votes)
{
d[e] = i;
e++;
}
}
printf("%sn", candidates[c].name);
for(int i = 0; i < (e + 1); i++)
{
if(candidates[c].votes == candidates[(d[i])].votes)
{
printf("%sn", candidates[d[i]].name);
}
}
return;
}
结果是:
:) plurality.c exists
:) plurality compiles
:) vote returns true when given name of first candidate
:) vote returns true when given name of middle candidate
:) vote returns true when given name of last candidate
:) vote returns false when given name of invalid candidate
:) vote produces correct counts when all votes are zero
:) vote produces correct counts after some have already voted
:) vote leaves vote counts unchanged when voting for invalid candidate
:) print_winner identifies Alice as winner of election
:) print_winner identifies Bob as winner of election
:) print_winner identifies Charlie as winner of election
:) print_winner prints multiple winners in case of tie
:( print_winner prints all names when all candidates are tied
print_winner function did not print all three winners of election
来源:
d[e] = i;
e++;
我们看到CCD_ 1比CCD_ 2中最后一个元素集合的索引大一。
然后:
for(int i = 0; i < (e + 1); i++)
{
if(candidates[c].votes == candidates[(d[i])].votes)
执行其中i
是e
并且因此d[i]
是d[e]
的迭代,其访问在d
中设置的最后一个元素之外的元素。此值未初始化,可能表现为具有非常大的正值或负值(因此,当表达式试图越界访问内存时会导致段错误(,或者具有较小的值,导致访问candidates
中某些不需要的元素(从而打印不正确的名称(,或者它可能在程序中具有其他不需要的行为。
将for
语句更改为:
for (int i = 0; i < e; i++)
当程序试图访问无效的内存地址时,会发生分段故障,例如,如果您试图访问向量e
1的a[10]
。请注意,C中的索引是基于零的,这意味着10
是第11个元素。它发生在代码的某些部分:
int d[candidate_count - 1];
...
for (int i = 1; i < candidate_count; i++)
{
if (candidates[c].votes < candidates[i].votes)
...
当上次迭代中的i = candidate_count - 1
时,索引i
超出了大小为candidate_count-1
的向量的限制。你可以试试这样的东西:
int d[candidate_count];
...
for (int i = 0; i < candidate_count; i++)
{
if (candidates[c].votes < candidates[i].votes)
...
请参阅维基百科上关于segfault 的文章