You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

投票统计程序处理大量数据时出现Segmentation fault及无效投票问题求助

问题描述

我编写的投票统计C语言程序在处理少量数据时可正常运行,但处理大量数据时出现异常:

  • 重复输入同一候选人姓名,第一次投票能正常增加票数,第二次却提示"invalid name"且不计数
  • 输入其他候选人姓名时触发"Segmentation fault (core dumped)"错误

程序代码如下:

#include <cs50.h>
#include <stdio.h>
#include <string.h>

// Max number of candidates
#define MAX 9

// Candidates have name and vote count
typedef struct
{
    string name;
    int votes;
}
candidate;

// Array of candidates
candidate candidates[MAX];

// Number of candidates
int candidate_count;

// Function prototypes
bool vote(string name);
void print_winner(void);
int largest(int list[], int n);

int main(int argc, string argv[])
{
    // Check for invalid usage
    if (argc < 2)
    {
        printf("Usage: plurality [candidate ...]\n");
        return 1;
    }

    // Populate array of candidates
    candidate_count = argc - 1;
    if (candidate_count > MAX)
    {
        printf("Maximum number of candidates is %i\n", MAX);
        return 2;
    }
    for (int i = 0; i < candidate_count; i++)
    {
        candidates[i].name = argv[i + 1];
        candidates[i].votes = 0;
    }

    int voter_count = get_int("Number of voters: ");

    // Loop over all voters
    for (int i = 0; i < voter_count; i++)
    {
        string name = get_string("Vote: ");

        // Check for invalid vote
        vote(name);
        if (strcmp(name, candidates[i].name) != 0)
        {
            printf("Invalid vote.\n");
        }
    }

    // Display winner of election
    print_winner();
}

// Update vote totals given a new vote
bool vote(string NAME)
{
    for (int i = 0; i < candidate_count; i++)
    {
        if (strcmp(NAME, candidates[i].name) == 0)
        {
            candidates[i].votes++;
        }
    }
    return false;
}

// Print the winner (or winners) of the election
void print_winner(void)
{
    int Votes_here[candidate_count];

    for (int j = 0; j < candidate_count; j++)
    {
        Votes_here[j] = candidates[j].votes;
    }


    for (int i = 0; i < candidate_count; i++)
    {
        if (candidates[i].votes == largest(Votes_here, candidate_count))
        {
            printf("%s\n", candidates[i].name);
        }
    }

    return;
}

int largest(int list[], int n)
{
   int i;
   int l = list[0];
   for (i = 1; i < n; i++)
   {
       if (list[i] > l)
           l = list[i];
   }

   return l;

}

期望程序能正确统计所有票数,并输出得票最多的获胜者。


问题分析与修复方案

1. 核心错误点:主循环无效投票判断逻辑错误

主函数遍历选民的循环用了变量i,之后直接用candidates[i].name和输入姓名对比——这里的i是选民的索引,不是候选人的索引!当选民数量超过候选人数量时,i会超出candidates数组范围,直接访问越界内存导致段错误;即使选民数少,也只会和第i个候选人对比,完全无法正确判断投票是否有效。

2. vote函数逻辑缺陷

vote函数找到匹配候选人后没有返回true,而是遍历完所有候选人后固定返回false,完全没发挥返回值的作用,无法给主函数传递投票是否有效的信号。

修复后的完整代码

#include <cs50.h>
#include <stdio.h>
#include <string.h>

// Max number of candidates
#define MAX 9

// Candidates have name and vote count
typedef struct
{
    string name;
    int votes;
}
candidate;

// Array of candidates
candidate candidates[MAX];

// Number of candidates
int candidate_count;

// Function prototypes
bool vote(string name);
void print_winner(void);
int largest(int list[], int n);

int main(int argc, string argv[])
{
    // Check for invalid usage
    if (argc < 2)
    {
        printf("Usage: plurality [candidate ...]\n");
        return 1;
    }

    // Populate array of candidates
    candidate_count = argc - 1;
    if (candidate_count > MAX)
    {
        printf("Maximum number of candidates is %i\n", MAX);
        return 2;
    }
    for (int i = 0; i < candidate_count; i++)
    {
        candidates[i].name = argv[i + 1];
        candidates[i].votes = 0;
    }

    int voter_count = get_int("Number of voters: ");

    // Loop over all voters
    for (int i = 0; i < voter_count; i++)
    {
        string name = get_string("Vote: ");

        // Check for invalid vote using vote function's return value
        bool valid = vote(name);
        if (!valid)
        {
            printf("Invalid vote.\n");
        }
    }

    // Display winner of election
    print_winner();
}

// Update vote totals given a new vote
bool vote(string NAME)
{
    for (int i = 0; i < candidate_count; i++)
    {
        if (strcmp(NAME, candidates[i].name) == 0)
        {
            candidates[i].votes++;
            return true; // 找到匹配后立即返回true
        }
    }
    return false; // 遍历完都没匹配,返回false
}

// Print the winner (or winners) of the election
void print_winner(void)
{
    int Votes_here[candidate_count];

    for (int j = 0; j < candidate_count; j++)
    {
        Votes_here[j] = candidates[j].votes;
    }

    int max_votes = largest(Votes_here, candidate_count);
    for (int i = 0; i < candidate_count; i++)
    {
        if (candidates[i].votes == max_votes)
        {
            printf("%s\n", candidates[i].name);
        }
    }

    return;
}

int largest(int list[], int n)
{
   int i;
   int l = list[0];
   for (i = 1; i < n; i++)
   {
       if (list[i] > l)
           l = list[i];
   }

   return l;
}

修复说明

  • 主函数中调用vote函数时接收其返回值,用该返回值判断投票是否有效,彻底避免了用选民索引访问候选人数组的越界问题。
  • vote函数在找到匹配候选人并增加票数后立即返回true,未找到则返回false,正确传递投票有效性状态。
  • 额外优化:print_winner中先计算出最大票数再遍历判断,避免重复调用largest函数,提升运行效率。

内容的提问来源于stack exchange,提问作者AA-SLF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 13:05:55