如何在t_list的void* content中存储不同结构体并实现类型转换?
解决方法:用t_list存储不同结构体的内存分配与类型转换
一、为不同结构体分配内存并存入t_list
核心逻辑是先给t_list节点分配内存,再给目标结构体(如t_cmd/t_env)分配内存,最后将结构体指针绑定到t_list的content成员。以存储t_cmd为例:
void lexical_analyze(char *cmdline, t_table **table) { cmdline = openquotes(cmdline); cmdline = find_replace(cmdline, (*table)->env); // 1. 分配t_list节点内存,必须做空指针检查 (*table)->cmds = malloc(sizeof(t_list)); if (!(*table)->cmds) { perror("malloc t_list failed"); exit(EXIT_FAILURE); } // 2. 分配t_cmd结构体内存 t_cmd *new_cmd = malloc(sizeof(t_cmd)); if (!new_cmd) { perror("malloc t_cmd failed"); free((*table)->cmds); // 避免内存泄漏 exit(EXIT_FAILURE); } // 3. 初始化t_cmd的成员(示例,实际根据业务逻辑赋值) new_cmd->cmd = strdup("ls"); new_cmd->path = strdup("/bin/ls"); new_cmd->istream = STDIN_FILENO; new_cmd->ostream = STDOUT_FILENO; // 4. 将t_cmd指针存入t_list的content (*table)->cmds->content = new_cmd; (*table)->cmds->next = NULL; // 初始化链表尾指针 }
存储t_env或t_heredoc的流程完全一致:分配对应结构体内存→初始化成员→赋值给content即可。
二、从void*转换回对应结构体类型
取出数据时直接用强制类型转换,把void*转成目标结构体指针即可:
// 假设current_node是t_list链表中的某个节点 // 取出t_cmd类型数据 t_cmd *cmd = (t_cmd *)current_node->content; printf("执行命令:%s\n", cmd->cmd); // 取出t_env类型数据 t_env *env = (t_env *)current_node->content; printf("环境变量:%s=%s\n", env->key, env->val);
关键注意事项
- 避免内存泄漏:释放
t_list节点时,要先释放content指向的结构体内存,再释放t_list节点本身。示例:void free_cmd_node(t_list *node) { if (!node) return; t_cmd *cmd = (t_cmd *)node->content; free(cmd->cmd); free(cmd->path); free(cmd); free(node); } - 保证类型匹配:
void*可以存任意指针,但转换时必须和存入的结构体类型一致,否则会触发未定义行为。如果需要区分不同类型,可以给t_list新增一个类型标记字段(比如enum { TYPE_CMD, TYPE_ENV, TYPE_HEREDOC } type;),转换前先判断类型。
内容的提问来源于stack exchange,提问作者Davit
相关产品推荐
相关产品推荐

