C语言单链表头删节点报0xC0000005错误 是否为内存分配问题
你遇到的0xC0000005错误是Windows平台下的内存访问违例(等价于Linux平台的段错误),本质是访问了无权访问的非法内存地址,和内存分配操作本身无关,是代码逻辑错误导致的,具体问题如下:
核心报错原因
1. 野指针/空指针访问
场景A:静态变量逻辑错误
你定义了静态局部变量static NODE* printer,静态变量只会初始化一次,生命周期和程序一致:
- 若第一次调用函数时,节点pages减完后仍大于0,你既没有把
printer置为NULL,也没有将节点插回链表,后续所有调用removelist都会因为printer != NULL跳过整个逻辑分支,功能完全失效。 - 若第一次调用时pages减到0,你调用了
free(printer)但没有把printer置为NULL,此时printer变成野指针,下次调用时访问printer->dataPtr就会直接触发访问违例,刚好对应你定位的报错行。
场景B:printf空指针解引用
你把原头节点赋值给printer后,立刻执行了list->head = list->head->next,如果原链表只有1个节点,执行完这句后list->head就变成NULL,后续printf语句直接访问list->head->dataPtr属于空指针解引用,会直接触发崩溃。
2. 结构体字段未初始化
createNode函数仅给NODEDATA的pages和priority字段赋值,docnum和cycles完全没有初始化,存储的是随机垃圾值,即使程序不崩溃,打印的信息也完全错误。
3. 内存泄漏隐患
你free节点printer时,没有提前释放节点内dataPtr指向的NODEDATA内存,这部分内存会永久泄漏。
4. 入参合法性校验缺失
如果调用removelist时传入的list本身是NULL,第一行访问list->head就会触发空指针解引用。
修复方案
1. 调整removelist逻辑,移除错误的静态变量
void removelist(LIST* list){ // 先校验入参合法性 if (list == NULL || list->head == NULL){ return; } // 取出当前头节点 NODE* old_head = list->head; NODEDATA* job_data = (NODEDATA*)old_head->dataPtr; // 处理当前打印任务 job_data->pages -= PAGEPERMINUTE; list->head = old_head->next; list->count--; // 打印当前处理的任务信息,不要访问新的头节点 printf(" Print Job Processed - Document Number: %d - Cycle Count: %d\n", job_data->docnum, job_data->cycles); if(job_data->pages <= 0){ // 先释放数据域,再释放节点,避免内存泄漏 free(job_data); free(old_head); } else { // 任务未打印完成,将节点插回头部(或按你的业务逻辑放到队列对应位置) old_head->next = list->head; list->head = old_head; list->count++; } }
2. 完善createNode字段初始化
全局维护一个文档序号计数器,给docnum和cycles赋值:
// 全局变量,每次创建节点自增 int global_doc_num = 1; NODE* createNode (){ NODE* nodePtr = malloc (sizeof (NODE)); nodePtr->next = NULL; int Pages = rand() % MAXPAGES; int prioritychance = rand() % 10; NODEDATA* data = malloc(sizeof (NODEDATA)); nodePtr->dataPtr = data; // 初始化所有字段 data->pages = Pages; if(prioritychance ==0){ data->priority = 1; } else if (prioritychance ==1 || prioritychance==2){ data->priority = 3; } else{ data->priority = 2; } data->docnum = global_doc_num++; data->cycles = 0; // 按业务需求调整初始值 return nodePtr; }
内容的提问来源于stack exchange,提问作者Ides784
相关产品推荐
相关产品推荐

