C语言malloc触发Access violation reading location错误排查
问题根因
报错的核心原因是内存分配逻辑和结构体定义不匹配:
你在linkedList.h中定义的Frame结构体,name和path成员是char*类型的指针,并非固定长度的字符数组。原代码仅为Frame结构体本身、FrameNode结构体本身申请了堆内存,没有为name、path两个指针申请专门存储字符串内容的内存空间。malloc申请到的内存内容是未初始化的随机值,此时newFrame->name和newFrame->path是指向非法地址的野指针,直接调用strcpy向野指针指向的地址写入数据,就会触发0xC0000005内存访问违例错误,和你遇到的报错表现完全一致。
修复方案
你可以根据实际需求二选一实现:
方案1:保留现有结构体的char*指针定义
如果要保留char*类型的成员,必须在分配Frame结构体内存后,额外为name、path申请存储字符串的内存,长度需要包含字符串末尾的\0结束符,同时增加内存分配失败的校验逻辑,避免内存泄漏。
修复后的createFrameNode实现代码如下:
#include <stdlib.h> #include <string.h> #include "linkedList.h" FrameNode* createFrameNode(char name[MAX_NAME], int duration, char path[MAX_PATH]) { // 分配节点内存 FrameNode* newNode = malloc(sizeof(FrameNode)); if (!newNode) return NULL; // 分配Frame结构体内存 Frame* newFrame = malloc(sizeof(Frame)); if (!newFrame) { free(newNode); return NULL; } // 为name分配字符串存储内存 size_t nameLen = strlen(name); newFrame->name = malloc(nameLen + 1); if (!newFrame->name) { free(newFrame); free(newNode); return NULL; } strcpy(newFrame->name, name); // 为path分配字符串存储内存 size_t pathLen = strlen(path); newFrame->path = malloc(pathLen + 1); if (!newFrame->path) { free(newFrame->name); free(newFrame); free(newNode); return NULL; } strcpy(newFrame->path, path); // 赋值其余成员 newFrame->duration = (unsigned int)duration; newNode->frame = newFrame; newNode->next = NULL; return newNode; }
注意:后续删除链表节点时,必须按照分配顺序逆序释放内存:先释放frame->name、frame->path,再释放frame,最后释放节点本身,否则会造成内存泄漏。
方案2:将结构体成员改为固定长度字符数组
如果你不需要动态调整字符串长度,可以直接修改linkedList.h中的结构体定义,把指针改为固定长度数组,这种情况下不需要单独为name、path二次分配内存,原代码的strcpy逻辑可以直接运行:
#define MAX_NAME 256 // 按你实际需求定义长度 #define MAX_PATH 1024 // Frame struct typedef struct Frame { char name[MAX_NAME]; unsigned int duration; char path[MAX_PATH]; } Frame; // Link (node) struct typedef struct FrameNode { Frame* frame; struct FrameNode* next; } FrameNode;
额外提醒
- 函数参数中写
char name[MAX_NAME]在C语言中会自动退化为char*类型,不会自动做长度校验,使用strcpy时要确保传入的字符串长度不超过预设的最大值,避免缓冲区溢出。 - 所有
malloc调用后都建议校验返回值是否为NULL,处理内存分配失败的边界场景。
内容的提问来源于stack exchange,提问作者Ziv Sion
相关产品推荐
相关产品推荐

