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

C语言realloc动态数组扩容失效,无法添加多名Player问题求助

问题分析与修复方案

核心错误点

  • 指针算术使用错误:temp+(sizeof(Player)*addedPlayerCounter) 写法错误。C语言中指针做加法时,编译器会自动将偏移量乘以指针指向类型的大小,这里多做了一次sizeof计算,导致越界访问,无法正确存储后续Player数据。
  • 未更新Team的players指针:realloc后得到的新指针temp没有赋值给team->players,导致Team始终持有初始的NULL指针,后续扩容操作相当于每次都重新从NULL分配,之前添加的Player数据全部丢失。
  • Player字段复制不完整:仅复制了playerName和pointsAverage,遗漏了uniformNumber和pointsOfLastFiveGames字段,数据不完整。
  • 内存泄漏:setPlayer返回的动态分配的tempPlayer没有释放,每次添加Player都会产生内存泄漏。
  • 结构体初始化语法错误:C语言不支持在结构体定义中直接给成员赋初始值(char *managerName = nullptr;),这是C++语法,会导致编译失败。

修复后的完整代码

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

#define NUM_OF_PLAYER_POINT 5  // 补充缺失的宏定义

struct Player {
    float pointsAverage;
    int uniformNumber;
    int pointsOfLastFiveGames[5];
    char *playerName;
};

struct Team {
    int numberOfPlayers;
    char *managerName;
    struct Player *players;
};

struct Player* setPlayer(){
    struct Player *player = (struct Player*)malloc(sizeof(struct Player));
    if (!player) {  // 增加内存分配失败检查
        perror("malloc failed for Player");
        exit(EXIT_FAILURE);
    }
    char name[81] = {0};
    int jerseyNumber = -1;
    int sumOfPoints = 0;
    int currentPoint = 0;
    
    printf("Player name?\n");
    scanf("%s", name);  // name本身是指针,无需&
    int nameLength = strlen(name);
    player->playerName = (char*)malloc(sizeof(char)*(nameLength + 1));
    if (!player->playerName) {
        perror("malloc failed for player name");
        free(player);
        exit(EXIT_FAILURE);
    }
    strcpy(player->playerName, name);
    
    printf("Jersey number?\n");
    scanf("%d",&jerseyNumber);
    player->uniformNumber = jerseyNumber;
    
    printf("Player point history?\n");
    int i;
    for (i=0; i<NUM_OF_PLAYER_POINT; i++) {
        scanf("%d",&currentPoint);
        player->pointsOfLastFiveGames[i] = currentPoint;  // 保存每场分数
        sumOfPoints+=currentPoint;
    }
    player->pointsAverage = (float)sumOfPoints / NUM_OF_PLAYER_POINT;  // 修正整数除法精度问题
    return player;
}

struct Team* setTeam(){
    struct Team *team = (struct Team*) malloc(sizeof(struct Team));
    if (!team) {
        perror("malloc failed for Team");
        exit(EXIT_FAILURE);
    }
    team->managerName = NULL;
    team->numberOfPlayers = 0;
    team->players = NULL;
    int usersChoice = -1;
    char name[81] = {0};
    
    printf("Hello, please enter manager's name:\n");
    scanf("%s", name);  // 去掉多余的&
    int nameLength = strlen(name);
    team->managerName = (char *)malloc(sizeof(char) * (nameLength + 1));
    if (!team->managerName) {
        perror("malloc failed for manager name");
        free(team);
        exit(EXIT_FAILURE);
    }
    strcpy(team->managerName, name);
    
    while (1){
        printf("Would you like to buy a player (1) yes (else) no?\n");
        scanf("%d",&usersChoice);
        if(usersChoice==1){
            struct Player* tempPlayer = setPlayer();
            // 扩容到当前人数+1的大小
            struct Player *temp = (struct Player*)realloc(team->players, sizeof(struct Player)*(team->numberOfPlayers + 1));
            if (!temp) {
                perror("realloc failed for players");
                // 分配失败时释放tempPlayer避免泄漏
                free(tempPlayer->playerName);
                free(tempPlayer);
                exit(EXIT_FAILURE);
            }
            team->players = temp;  // 更新Team的players指针
            // 复制tempPlayer所有字段到新位置
            team->players[team->numberOfPlayers] = *tempPlayer;
            // 释放tempPlayer,内容已复制到team的数组中
            free(tempPlayer);
            team->numberOfPlayers++;
        }else{
            return team;
        }
    }
}

// 主函数示例
int main() {
    struct Team *myTeam = setTeam();
    // 后续可添加打印Team信息的代码
    // 记得最后释放所有动态分配的内存避免泄漏
    return 0;
}

额外优化说明

  • 增加内存分配失败检查,避免空指针访问。
  • 修正setPlayer中整数除法的精度问题,改为先转float再执行除法。
  • 简化计数逻辑,直接用team->numberOfPlayers跟踪当前玩家数量,减少冗余变量。
  • 修复scanf("%s", &name)的错误,数组名本身就是指针,无需取地址符&。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:03:19