You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 14:10:36