链表容器结构体t_holder的解引用方法及访问错误问题咨询
错误原因与正确解引用方法
错误原因
- 空指针解引用:
main函数中你将list_holder赋值为NULL,在try_out里尝试访问list_holder->a_starts时,本质是对空指针进行解引用,这是C语言中明确的非法操作,直接触发内存访问错误。 - 未初始化的链表指针:即使你为
list_holder分配了有效内存,a_starts默认是未初始化的野指针(指向随机内存地址),访问a_starts->val依然会导致非法内存访问。
正确实现步骤
要安全操作结构体中的链表,需要完成以下几步:
- 为
t_holder结构体分配有效内存(堆内存或栈上实例),让指针指向合法的结构体对象。 - 为
a_starts指向的链表节点分配内存,初始化节点的val和next字段。 - (推荐)在访问指针前添加非空检查,避免意外的空指针访问。
- 程序结束时释放分配的内存,避免内存泄漏。
修正后的代码示例
堆内存分配版本
#include <stdlib.h> typedef struct s_list { int val; struct s_list *next; } t_list; typedef struct s_holder { t_list *a_starts; // more lists... } t_holder; void try_out(t_holder *list_holder, int num) { // 先检查指针有效性,避免空指针访问 if (list_holder == NULL || list_holder->a_starts == NULL) return; list_holder->a_starts->val = num; } int main(int argc, char *argv[]) { t_holder *list_holder; t_list *new_node; int num; num = 42; // 为t_holder分配堆内存 list_holder = malloc(sizeof(t_holder)); if (list_holder == NULL) return 1; // 为链表节点分配内存并初始化 new_node = malloc(sizeof(t_list)); if (new_node == NULL) { free(list_holder); return 1; } new_node->val = 0; // 设置初始值 new_node->next = NULL; list_holder->a_starts = new_node; // 调用函数完成赋值 try_out(list_holder, num); // 释放内存,避免泄漏 free(new_node); free(list_holder); return (0); }
栈内存实例版本(无需malloc结构体)
如果t_holder不需要长期存活,可以直接在栈上声明实例:
#include <stdlib.h> typedef struct s_list { int val; struct s_list *next; } t_list; typedef struct s_holder { t_list *a_starts; // more lists... } t_holder; void try_out(t_holder *list_holder, int num) { if (list_holder == NULL || list_holder->a_starts == NULL) return; list_holder->a_starts->val = num; } int main(int argc, char *argv[]) { t_holder list_holder; // 栈上实例,无需malloc t_list *new_node; int num; num = 42; // 为链表节点分配内存 new_node = malloc(sizeof(t_list)); if (new_node == NULL) return 1; new_node->val = 0; new_node->next = NULL; list_holder.a_starts = new_node; // 传入结构体地址调用函数 try_out(&list_holder, num); // 释放节点内存 free(new_node); return (0); }
内容的提问来源于stack exchange,提问作者mariekart42
相关产品推荐
相关产品推荐

