通过类型转换在 C 中自由动态分配结构

Free dynamically allocate struct in C by typecasting

我有一个定义为

的结构
typedef struct
{
    int id;
    char* name;
    float percentage;
}student_t;

并且在给定的函数中

void student_tDeleter(void* val_ref) {
    
}

我知道如果一个函数必须接受 void* ptr 作为它的参数,我必须进行类型转换才能访问它的 memeber 变量,但是下面的代码由于某些原因无法工作

void student_tDeleter(void* val_ref) {
    free((student_t*)val_ref->id);
    free((student_t*)val_ref->name);
    free((student_t*)val_ref->percentage);
    free(val_ref)
    val_ref = NULL;
}

编译器说```警告:取消引用 void* 指针 错误:请求成员“id/name/percentage”不是结构或联合

我以为是括号。所以我加了两个额外的括号

void student_tDeleter(void* val_ref) {
    free(((student_t*)val_ref)->id);
    free(((student_t*)val_ref)->name);
    free(((student_t*)val_ref)->percentage);
    val_ref = NULL;
}

但是编译器说

  free(((student_t*)val_ref)->id);
error: incompatible type for argument 1 of ‘free’
  free(((student_t*)val_ref)->percentage);
 note: expected ‘void *’ but argument is of type ‘float’
 extern void free (void *__ptr) __THROW;

我如何正确地 free() 结构成员? 如有任何回复,我们将不胜感激。

Operator precedence

-> 击败 cast.

(student_t*)val_ref->id
// is like
(student_t*)(val_ref->id)

改为使用

((student_t*)val_ref)->id

免费指点

很好地指出代码不应尝试“释放”floatint.


修复代码

由于free(NULL)可以,让我们也允许student_tDeleter(NULL)

void student_tDeleter(void* val_ref) {
  if (val_ref) {
    free(((student_t*)val_ref)->name);
    free(val_ref)
  }
}

数据成员idpercentage不是指针。

typedef struct
{
    int id;
    char* name;
    float percentage
}student_t;

因此,将函数 free 应用于 intfloat.

类型的对象没有任何意义

如果数据成员name指向一个动态分配的内存那么你需要写

free( ( ( student_t * )val_ref )->name );

然后

free(val_ref)

注意转换是一元运算符,而运算符->是后缀运算符,优先级高于一元运算符。

您的结构的非动态分配成员将由 freeing 结构处理。您只需要单独释放任何动态分配的结构成员。

例如:

typedef struct a {
    int b;
    char *c;
} a_t;

a_t * create_a() {
    a_t *new_a = malloc(sizeof(a_t));

    new_a->b = 42;
    new_a->c = malloc(new_a->b);

    return new_a;
}

void delete_a(void *d) {
    a_t *a = (a_t *)d;

    free(a->c);
    free(a);
}