【问题标题】:How do I free this structure in C?如何在 C 中释放这个结构?
【发布时间】:2026-01-30 03:35:02
【问题描述】:

我有这个大学项目,我必须创建一个库来处理来自终端的可执行文件的选项。

我创建了这个结构 options_s:

typedef struct option_s option_t;
struct option_s {
    char* keyword;
    enum { 
        OptVoid, 
        OptInt, 
        OptString, 
        OptFloat 
    } spec;
    union {
        void (*opt_void)();
        void (*opt_int)(int);
        void (*opt_str)(const char*);
        void (*opt_float)(float);
    } fct;
    option_t* next;
};

每个选项类型变量都将包含一个函数,该函数将 int、float、string 或任何内容作为参数。关键字是终端中选项的标识符,例如“-o”,位于将传递给函数的值之前。

这就是我如何初始化一个以和 int 作为参数的选项:

option_t* c_null(option_t* l, const char* kw){
    l = (option_t*) malloc (sizeof(option_t));
    l->keyword = (char*) malloc (strlen(kw) + 1);
    strcpy(l->keyword, kw);
    l->next = NULL;
    return l;
}


option_t* common(option_t* l, const char* kw){
    while(l->next != NULL) l = l->next;
    l->next = (option_t*) malloc (sizeof(option_t));
    l->next->keyword = (char*) malloc (strlen(kw) + 1);
    strcpy(l->next->keyword, kw);
    l->next->next = NULL;
    return l->next;
}

option_t* opt_int(option_t* l, const char* kw, void (*f)(int)){
    if(l == NULL){
        l = c_null(l, kw);
        l->spec = OptInt;
        l->fct.opt_int = f;
        return l;
    }else{
        option_t* o = common(l, kw);
        o->spec = OptInt;
        o->fct.opt_int = f;
        return l;
    }
}

我在释放选项时遇到问题。我为此编写了这个函数:

void opt_delete(option_t* l){
    if(l->next != NULL) opt_delete(l->next);
    free(l->keyword);
    free(l);
}

这似乎不起作用。即使通过此函数运行了一个接收字符串的选项,执行opt->fct.opt_str("foo"); 仍然会打印“foo”。

我的代码可能有什么问题?

【问题讨论】:

  • free() 不会使内存为空或无法访问,它只会使访问它成为未定义的行为。
  • Names that end with ‘_t’ are reserved for additional type names. 。换句话说,您不应该使用名称option_t
  • 好的,谢谢。我不确定是否存在实际错误。
  • 您没有包含任何打印出任何内容的代码,因此不清楚如何或为什么会打印出“foo”?
  • @WilliamPursell Names that end with ‘_t’ are reserved for additional type names. 但我认为只有以intuint 开头(参考7.31.10)。

标签: c memory-management malloc dynamic-memory-allocation free


【解决方案1】:

free() 函数不清理内存,它只是从进程中释放内存,并让释放的空间被另一个 malloc() 重新分配。

这意味着如果你尝试访问一块被释放的内存,你可以找到你写入的最后一个值。但这只是幸运的情况,因为访问一块被释放或未分配的内存区域是未定义的行为。

这个问题可以帮到你:How do malloc() and free() work?

【讨论】: