【发布时间】:2019-06-12 12:28:34
【问题描述】:
我试图了解提供结构的创建/回收功能的常见习语(良好做法)是什么。这是我尝试过的:
struct test_struct_t{
int a;
};
struct test_struct_t *create(int a){
struct test_struct_t *test_struct_ptr = malloc(sizeof(*test_struct_ptr));
test_struct_ptr -> a = a;
return test_struct_ptr;
}
void release(struct test_struct_t *test_struct_ptr){
free((void *) test_struct_ptr);
}
int main(int argc, char const *argv[])
{
const struct test_struct_t *test_struct_ptr = create(10);
release(test_struct_ptr); // <--- Warning here
}
我收到了警告
passing argument 1 of ‘release’ discards ‘const’ qualifier from pointer
target type [-Wdiscarded-qualifiers]
这很清楚。所以我倾向于将回收方法定义如下:
void release(const struct test_struct_t *test_struct_ptr){
free((void *) test_struct_ptr);
}
警告消失了,但我不确定它是否容易出错。
那么将结构回收方法参数定义为指向 const 结构的指针是一种常见的做法,这样我们就可以避免在任何时候强制转换为非 const,并在回收方法实现中执行一次这种脏强制转换?
【问题讨论】:
-
通常,只有在结构具有需要首先释放的已分配指针成员,然后才能释放指向结构的指针时,才会执行这些清理功能。它应该始终与分配顺序相反。最后,悬空指针应设置为 NULL。
-
@Rafael 但是如何在清理函数中隐藏释放细节呢?因此,我们不必在整个代码库中用自定义 dealloc 函数替换
free,以防我们复杂化... -
起初对我来说似乎是个坏主意,只有 const 指针用于动态分配的对象。
-
@SomeName 是的。您的假设是正确的,但是由于您需要稍后对其进行修改(
free(3)),因此您至少应该有一个指向它的非常量指针,以避免出现这样的警告。 -
一种常见的做法是使用“不透明指针”并且根本不将结构暴露给调用者。给调用者一个指向不完整类型的指针。在这种情况下,您不需要
const限定符,因为调用者无法对指针做任何有意义的事情。
标签: c struct free const-pointer