假设我有以下内容:
typedef struct a_struct_s
{
int* dynamic_pointer;
}
a_struct;
a_struct make_struct( int length )
{
a_struct s;
s.dynamic_pointer = calloc( sizeof( int ), length );
// [check here to see if s.dynamic_pointer was allocated]
return s;
}
由于make_struct()
将返回结构s
的副本,由它封装的指针是否会泄漏内存并且无法释放?此外,复制本身与动态分配s
是否有性能成本?
答案 0 :(得分:2)
没有。即使你复制了指针,它仍然指向同一个地方,所以你可以释放它。
答案 1 :(得分:2)
为什么会这样?指针不是分配的内存本身 - 如果你复制指针,它本身不分配内存。如果您稍后在其上调用free()
,它将被正确释放。例如,这段代码不会泄漏内存:
a_struct s = make_struct(10);
free(s.dynamic_pointer);
答案 2 :(得分:1)
不,只要函数的调用者在结构指针成员上调用free()
,它就不会泄漏内存。
记住规则:
当您拨打malloc
,calloc
并且从不在同一地址呼叫free
时,会发生内存泄漏。只要你这样做,就没有内存泄漏。
请注意,从函数返回动态分配的指针时,指定所有权语义非常重要。简而言之,您的接口应明确提到在函数调用之后,动态分配的指针成员由调用者拥有。
由于
make_struct()
将返回struct s
的副本,由它封装的指针是否会泄漏内存并且无法释放?
是的,会返回结构的副本,但 shallow copy
基本上,这意味着返回的结构副本的指针成员指向与s
的结构指针成员指向的内存位置相同的内存位置。
由于两个指针都指向同一个地址,只要调用者在返回结构的指针成员上调用free
就没有泄漏。
副本本身是否会产生性能成本与动态分配
s
相比?
动态分配总是昂贵且更容易出错。尽量使用它们,除非你真的需要它们,否则不要使用它们。
答案 3 :(得分:1)
不,从你的角度来看它很好但是你可能想要考虑另一种分配方法,因为通过值返回一个带有指向内存块的指针的结构可能不那么明显,调用者需要释放其中的成员。
一种方法是使整个结构分配,然后有一个函数释放结构
a_struct* alloc_struct( int length )
{
a_struct s = calloc( 1, sizeof(a_struct) );
s->dynamic_pointer = calloc( sizeof( int ), length );
return s;
}
void free_struct( a_struct *p )
{
if ( p != NULL )
{
free( p->dynamic_pointer );
free(p);
}
}