c - C 内存管理约定:通过在堆栈上分配的对象释放在堆上分配的内存
问题描述
我想我对 C 中的内存管理约定有点困惑。
假设我们有一个在堆上动态分配数据的结构。此结构提供用于在堆上分配_alloc()
和_free()
释放此结构的功能。
这是一个带有简单向量结构的示例:
struct vec_t {
int *items;
size_t size;
size_t capacity;
};
struct vec_t *vec_alloc(void)
{
struct vec_t *vec = malloc(sizeof(struct vec_t));
vec->items = NULL;
vec->size = 0;
vec->capacity = 0;
return vec;
}
void vec_free(struct vec_t *vec)
{
free(vec->items);
free(vec);
}
void vec_push(struct vec_t *vec, int item)
{
if (vec->size == vec->capacity)
{
size_t new_capacity = vec->capacity > 0 ? (vec->capacity + 1) * 2 : 5;
vec->items = realloc(vec->items, new_capacity * sizeof(int));
}
vec->items[vec->size++] = item;
}
现在让我们假设我们不使用_alloc()
or_free()
而是决定在堆栈上分配这个结构。
然后我们通过栈分配的struct( my_vec.items
)间接在堆上分配数据
void main()
{
vec_t my_vec;
vec_push(&my_vec, 8); // allocates memory
// vec_destroy(&my_vec); // PROBLEM
return 0;
}
现在我们有一个问题:我们不想释放my_vec
堆栈上的结构(),但我们需要释放堆(my_vec.items
)上的结构分配的数据。
我相信这要么是设计问题,要么是约定问题,或者两者兼而有之。
我已经看到人们添加了一些额外的功能_init()
,_deinit()
除了_alloc()
and之外_free()
。
void vec_init(struct vec_t *vec)
{
vec->items = NULL;
vec->size = 0;
vec->capacity = 0;
}
void vec_deinit(struct vec_t *vec)
{
free(vec->items);
}
释放结构分配的内存是否有意义_deinit()
?
如果这种方法是正确的,我是否正确地说像这样分配在堆栈上的结构总是需要是_init()
and _deinit()
?
解决方案
如果您使用_init
and_deinit
函数,是的,您想要_deinit
释放内存,是的,vec_init
并且vec_deinit
对于堆栈分配的结构是强制性的。对于这个用例,可以初始化堆栈分配的结构并避免vec_t my_vec = {0};
调用vec_init
,但假设归零现在和永远产生一个有效初始化的结构(如果您vec_init
稍后更改以使某些字段非零,则您的库的用户没有' t 使用vec_init
必须更新),并且当不可避免vec_deinit
的未与相应的vec_init
.
请注意,代码不需要如此大量地重复;_alloc
和_free
可以用 和 来实现_init
,_deinit
将代码重复保持在最低限度:
struct vec_t *vec_alloc(void)
{
struct vec_t *vec = malloc(sizeof(struct vec_t));
if (vec) vec_init(vec); // Don't try to init if malloc failed
return vec;
}
void vec_free(struct vec_t *vec)
{
if (vec) vec_deinit(vec); // Don't try to deinit when passed NULL
free(vec);
}
推荐阅读
- c# - 如何解决错误查询值和目标字段的数量不一样。在 c# windows 应用程序中
- mysql - 创建数据库时在 MySQL 中使用默认字符集和使用默认字符集有什么区别
- google-sheets - 是否可以为从 UNIQUE 生成的范围创建过滤器?
- python - 需要帮助让这个递归函数工作
- ubuntu-12.04 - Ubuntu 12.04 - libc.so.6:未找到版本“GLIBC_2.16”
- python - Openpyxl 将 100% 读取为“int”
- r - 将误差线添加到绘图箱图中的点
- sql - 将变量从存储过程传递给另一个
- ejabberd - 我收到了这个错误,ld: library not found for -lerl_interface
- python - 如何将 JSON 字符串分配给 POST 请求中的变量,以便在函数中使用?