c中联合的自由结构

free struct of unions in c

我有一个特殊结构的动态分配向量,我试图释放但软件总是崩溃

结构是:

typedef struct {
    Type_e type;
    union {
        char m_char;
        int m_int;
        // more types (non of them is a pointer)
    } my_data;
} Data_t;

其中 Type 是一个包含所有可能数据类型的枚举。

我分配和初始化向量如下

void vector(Data_t **vec, UInt32_t start_element, UInt32_t end_element, Type_e type)
{
    UInt32_t i;
    Data_t  *vec_ptr;

    *vec=(Data_t *)malloc((size_t) ((end_element-start_element+1) * sizeof(Data_t)));

    vec_ptr = *vec;

    if (!vec_ptr) 
    {
        // Write error 
    }

    for (i =start_element; i <= end_element + 1; i++)
    {
        vec_ptr->type = type;
        switch (type)
        {
        case UINT32: vec_ptr->my_data.m_int = 0; break;
        // more possible cases
        default:
            break;
        }
        (vec_ptr)++;
    }
}

我调用这个函数如下

Data_t *lVector = NULL;
vector(&lVector,0,10,INT32)

但是当我尝试如下释放分配的内存时,

free (lVector+start_element-1);

我试过了

free (lVector+start_element);

free (lVector);

是 start_element = 0(在这种情况下)

但在所有情况下,它都会崩溃。我做错了什么吗?

这是不正确的:

*vec  = *vec + sizeof(Data_t);

它将 *vec 前进 sizeof(Data_t)*sizeof(Data_t) 字节,因为指针运算会自动将整数常量乘以 sizeof(*p)

替换为(*vec)++,让编译器为您计算。同样,在所有操作指针的地方删除乘法。代码中唯一需要乘以 sizeof 的地方是调用 malloc.

注意: 您的代码很难阅读,因为您在循环中来回移动 *vec。您最好声明并使用一个普通的临时指针来迭代向量,并将 *vec 固定为 malloc.

分配的任何内容

你想在哪里打电话给 free()

如果在 vector() 内,您将释放 '&lVector',它在堆栈上并且无法被释放。

你只能释放你用malloc()分配的space,所以你可以释放*vec,但不能释放vec.

您必须 free 完全由 malloc 编辑的指针 return,并且只这样做一次。您将 malloc 的 return 值存储在 *vec 中,因此 free(*vec) 在同一函数中或 free(lVector) 在调用函数中是正确的。 但是,您随后将其他值分配给 *vec,因此为了能够 free 它正确,您需要以某种方式恢复原始 return 值malloc(更好的选择几乎肯定是使用另一个变量)。

你好像也误解了指针运算。 p += n 已经推进了 sizeof(*p) * n 指向的地址。因此,您不能将 *vec 的更改乘以 sizeof(Data_t)(即 sizeof(**vec))。

这个参数表示指向类型 'Data_t'

的指针数组
Data_t **vec,

但是,这一行:

*vec=(Data_t *)malloc((size_t) ((end_element-start_element+1) * sizeof(Data_t)));

为 'Data_t' 的数组分配内存,而不是指向 'Data_t'

的指针数组

在 C 中,不要转换 malloc 的返回值

malloc() 的参数自动为 'size_t',因此转换为 'size_t' 只会使代码混乱


这一行:

for (i =start_element; i <= end_element + 1; i++)

从索引 0 到索引 11 遍历数组,但是,有效索引是从 0 到 10,因为 C 数组索引从 0 开始到 sizeof(array) -1


这一行:

(*vec)->type = type;

期望 'vec' 实际上是指向结构的指针数组。但是,如前所述,它不是


这一行:

*vec  = *vec + sizeof(Data_t);

正在正确地遍历结构数组 但是,这会丢失指向 malloc 内存的指针,导致内存泄漏,因为指向 malloc 内存的指针丢失,因此无法传递给 free()


这一行:

*vec = *vec - ((end_element-start_element+1) * sizeof(Data_t));

不太有效,因为前面的 'for' 语句重复了太多次。

强烈建议关闭索引 'vec' 而不是更改 vec 内容。 IE。 vec[i]