动态分配缓冲区的链表运行异常,静态分配可正常工作
问题分析与修复方案
核心崩溃原因
你代码里的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
相关产品推荐
相关产品推荐

