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

C语言结构体链表打印结构体数组元素异常问题求助

问题分析与解决:C语言链表中候选人姓名打印异常

你遇到的问题核心是结构体设计错误+内存越界访问,导致链表节点只保存了第一个候选人的信息,其余候选人的信息根本没被正确存入链表节点。

原因拆解

1. 结构体设计不符合需求

你的election结构体里只定义了一个char name_candidate[n]数组,这只能存一个候选人的名字。但你在createElection里用(pole+i)->name_candidate来写入第i个候选人的名字,本质是把pole(也就是info指针)当成了election数组来操作——但info只通过malloc(sizeof(election))申请了单个election的内存空间,后续的(pole+1)、(pole+2)都是越界访问info后面的未知内存。

直接打印info时能显示所有候选人名字,纯粹是因为那段越界的内存暂时还没被其他操作覆盖,属于“侥幸”行为,本身已经是非法内存访问了。

2. 链表插入时只复制了单个election的内容

insertElection里执行newnode->voting = *info;,只会复制单个election结构体的内容——也就是info指向的第一个election大小的内存,而你越界写入到info后面的候选人名字,根本不会被复制到链表节点里。

3. 打印函数的遍历逻辑错误

在printElection里,你用(tmp+i)->voting.name_candidate来获取第i个候选人的名字,这里的tmp是链表节点指针,tmp+i会指向链表的第i个节点(甚至越界),而不是当前节点里的第i个候选人。每个链表节点的voting成员只有一个name_candidate,所以后面的打印自然是空的。

解决步骤

步骤1:修改election结构体,支持存储多个候选人名字

把name_candidate改成二维数组(假设最多存10个候选人,可按需调整):

typedef struct pole{
   int year;
   char county[n];
   char ID_election[n];
   char ID_electionUser[n];
   int num_candidates;
   char name_candidate[10][n]; // 改成二维数组,存多个候选人名字
   int limit_votes;
}election;

如果候选人数量不确定,也可以用动态分配的指针数组,比如char **name_candidate;,但二维数组实现更简单。

步骤2:修正createElection的写入逻辑

不再用越界的(pole+i),直接访问二维数组的对应索引:

void createElection(node_pole *head_pole, election *info){
        election *pole = info;    
        int i = 0;

        printf("\nInsert data:  \n Year: ");
        scanf("%d", &pole->year);
        printf(" County:");
        scanf("%s", pole->county);
        printf(" Voters' limit:");
        scanf("%d", &pole->limit_votes);  
        printf("ID_Election: ");         
        scanf("%s", pole->ID_election);
        printf("ID_Election_User: ");         
        scanf("%s", pole->ID_electionUser);
        printf("Candidates' number: ");
        scanf("%d", &pole->num_candidates);
        // 检查候选人数量不超过数组上限
        if(pole->num_candidates > 10){
            printf("Too many candidates, max 10 allowed.\n");
            pole->num_candidates = 10;
        }
        for(i = 0; i < pole->num_candidates; i++){  
                printf("\n Candidates' names [%d]:", i+1);
                scanf("%s", pole->name_candidate[i]); // 直接访问二维数组的第i行
        }                
        return;
}

步骤3:修正printElection的遍历逻辑

直接访问当前节点voting成员里的二维数组:

void printElection(node_pole *head_pole){
    int i;
    node_pole *tmp = head_pole;
    
    if(tmp == NULL){
            printf("\nNo poll in the database.");
            return;
    }
    while(tmp != NULL){
        printf("\n----- Your election ----- ");
        printf("\nID Election:%s \nID Elect_User: %s  \nYear:%d \nCounty:%s  \nMax voters:%d", 
               tmp->voting.ID_election, tmp->voting.ID_electionUser, tmp->voting.year, 
               tmp->voting.county, tmp->voting.limit_votes);
        printf("\nCandidates' number:%d", tmp->voting.num_candidates);
        for(i = 0; i < tmp->voting.num_candidates; i++){
            printf("\nCandidates' name [%d]: %s", i + 1, tmp->voting.name_candidate[i]); // 访问当前节点的候选人数组
        }                    
        tmp = tmp->next_pole;
    }
    return;
}

步骤4:修正主函数里的打印逻辑

同样改成访问二维数组,避免之前的越界访问:

for(i = 0; i < info->num_candidates; i++){
    printf("\nCandidates' name [%d]: %s", i+1, info->name_candidate[i]);
}

额外提醒

  • 之前的(pole+i)->name_candidate属于未定义行为,虽然暂时能显示,但随时可能因为内存被覆盖导致程序崩溃或输出乱码,必须修正。
  • 如果候选人数量动态变化,建议用指针数组+动态分配:在createElection里根据num_candidates为name_candidate分配内存,记得在销毁链表时释放,避免内存泄漏。

内容的提问来源于stack exchange,提问作者DM10

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:45:00