提问人:Jeffrey Bonde 提问时间:10/3/2022 更新时间:10/3/2022 访问量:175
malloc'd 结构内按值传递的指针
malloc'd pointer inside struct that is passed by value
问:
我正在用 C 语言组合一个项目,其中我必须传递一个可变长度的字节序列,但由于堆可能有限,我正在尝试限制 malloc 调用。
假设我有一个结构体,它包含可变长度字节序列 ,以及一个函数 ,它创建一个 的实例。在 中,是 malloc'd,并按值返回。 然后将由 value 传递的其他函数使用: 。代码如下。my_struct
ptr
my_func
my_struct
my_func
my_struct.ptr
my_struct
my_struct
another_func
- 这是否“安全”,可以防止在原始副本或任何副本上提供的内存泄漏,当按值传递时,我调用或释放 malloc'd 指针?具体来说,有没有办法在返回时可以被重写或悬而未决?
my_struct
my_struct_destroy
another_func
inst.ptr
- 由于 stackoverflow 不喜欢基于意见的问题,是否有任何好的参考资料来讨论这种行为?我不确定要搜索什么。
typedef struct {
char * ptr;
} my_struct;
// allocates n bytes to pointer in structure and initializes.
my_struct my_func(size_t n) {
my_struct out = {(char *) malloc(n)};
/* initialization of out.ptr */
return out;
}
void another_func(my_struct inst) {
/*
do something using the passed-by-value inst
are there problems with inst.ptr here or after this function returns?
*/
}
void my_struct_destroy(my_struct * ms_ptr) {
free(ms_ptr->ptr);
ms_ptr->ptr = NULL;
}
int main() {
my_struct inst = my_func(20);
another_func(inst);
my_struct_destroy(&inst);
}
答:
我可以安全地传递并返回一个包含按值指针的结构,就像你所做的那样。它包含 的副本。调用函数中没有任何更改。当然,如果释放,然后调用者尝试使用它或再次释放它,则会出现一个大问题。
ptr
another_func
ptr
alloc+free 的位置是最佳做法。在可能的情况下,使分配对象的函数也负责释放它。如果不可行,malloc 和 free of the same object 应该位于同一个源文件中。如果这是不可能的(想想带有删除的复杂图形数据结构),则应清楚地标识管理给定类型对象的文件集合并记录约定。有一种常见的技术对于分阶段工作的程序(如编译器)很有用,其中一个阶段分配的大部分内存应该在下一个阶段开始之前释放。在这里,内存只由经理以大块的形式进行。从这些对象中,管理器分配任何大小的对象。但它只知道一种自由的方式:一次全部,大概在一个阶段的尽头。这是一个想法:obstacks。当分配更复杂时,较大的系统会实现某种垃圾回收器。除了这些想法之外,管理 C 存储的方法与颜色一样多。对不起,我没有任何指向参考文献的指针(双关语:)
malloc
gcc
如果只有一个可变长度字段,并且不需要动态更新其大小,请考虑将结构中的最后一个字段设置为数组来保存它。这在 C 标准中是可以的:
typedef struct {
... other fields
char a[1]; // variable length
} my_struct;
my_struct my_func(size_t n) {
my_struct *p = malloc(sizeof *p + (n - 1) * sizeof p->a[0]);
... initialize fields of p
return p;
}
这样就避免了单独释放可变长度字段的需要。不幸的是,它只适用于一个。
如果您对 gcc 扩展感到满意,则可以分配大小为零的数组。在 C 99 中,您可以使用 获得相同的效果。这样可以避免在大小计算中。a[]
- 1
评论
char a[];
char a[1];
char a[];
my_func(0)
(n - 1) * sizeof p->a[0]
评论
my_struct