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

动态分配缓冲区的链表运行异常,静态分配可正常工作

问题分析与修复方案

核心崩溃原因

你代码里的GameLinkedList *gm;是未初始化的野指针,直接访问gm->head会触发非法内存访问,这就是程序崩溃的根本原因。而且刚用malloc创建的newNode,立刻被newNode = gm->head覆盖,不仅丢了刚分配的内存造成泄漏,还让newNode变成野指针,操作它的title自然会崩溃。

其他明显错误

  • 错误处理逻辑混乱:比如newNode->title分配失败时,还去free(newNode->title),此时它是NULL,虽然free(NULL)没问题但完全多余;genre分配失败时重复free(newNode->genre)两次,属于无效操作。
  • 函数声明返回GameNode*,但代码末尾没有任何返回语句,违反C语言语法。
  • 链表添加逻辑错误:没有正确将新节点插入链表,只是盲目操作野指针。

修复后的代码示例

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

// 保留原结构体定义
typedef struct game_node {
    char* title;
    char* genre;
    int year;
    float rating;
    struct game_node* next;
    struct dlc_node* dlc_head;
}GameNode;

typedef struct dlc_node {
    char* title;
    float price;
    struct dlc_node* next;
}DLCNode;

typedef struct {
    GameNode* head;
}GameLinkedList;

// 修复后的GameAdd函数,接收外部传入的链表指针
GameNode* GameAdd(GameLinkedList *gm){
    // 校验传入的链表指针是否有效
    if(gm == NULL){
        return NULL;
    }

    char *buffer = malloc(256 * sizeof(char));
    if(buffer == NULL){
        return NULL;
    }

    GameNode *newNode = malloc(sizeof(GameNode));
    if(newNode == NULL){
        free(buffer);
        return NULL;
    }
    // 初始化新节点的指针成员,避免野指针
    newNode->next = NULL;
    newNode->dlc_head = NULL;

    // 获取游戏标题
    printf("Game Title - ");
    scanf("%s", buffer);
    
    newNode->title = malloc(strlen(buffer) + 1);
    if(newNode->title == NULL){
        free(buffer);
        free(newNode);
        return NULL;
    }
    strcpy(newNode->title, buffer);

    // 获取游戏类型
    printf("Game Genre - ");
    scanf("%s", buffer);
    
    newNode->genre = malloc(strlen(buffer) + 1);
    if(newNode->genre == NULL){
        free(newNode->title);
        free(buffer);
        free(newNode);
        return NULL;
    }
    strcpy(newNode->genre, buffer);

    // 将新节点插入链表头部(可根据需求改成尾部插入)
    newNode->next = gm->head;
    gm->head = newNode;

    free(buffer);
    return newNode;
}

// 示例调用
int main(){
    GameLinkedList list;
    list.head = NULL;
    GameAdd(&list);
    return 0;
}

关键修复点说明

  • 让GameAdd函数接收外部传入的GameLinkedList指针,避免内部定义未初始化的野指针。
  • 新节点创建后,初始化它的next和dlc_head为NULL,防止后续操作出现野指针。
  • 修正错误处理逻辑:分配失败时按顺序释放已分配的内存,避免内存泄漏。
  • 实现正确的链表插入逻辑(这里用头部插入,可根据需求调整)。
  • 函数末尾返回正确的指针或NULL,符合返回类型要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:57:29