0

假设我有以下内容:

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()会返回 struct 的副本,那么s被它封装的指针会不会泄漏内存而无法释放?此外,副本本身与动态分配是否有性能成本s

4

4 回答 4

2

不,即使你复制了指针,它仍然指向同一个地方,所以你可以释放它。

于 2013-01-22T06:27:01.957 回答
2

为什么会呢?指针本身不是分配的内存 - 如果您复制指针,它本身不会分配内存。如果您稍后调用free()它,它将被正确释放。即,此代码不会泄漏内存:

a_struct s = make_struct(10);
free(s.dynamic_pointer);
于 2013-01-22T06:27:24.890 回答
1

no, its fine as you have it from that point of view however you may want to consider having another approach to allocating because returning a struct by value with a pointer to a memory block may not be so obvious that the caller needs to free a member in it.

one approach would be to make the whole struct allocated as well then have a function the free the struct

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);
    }
}
于 2013-01-22T06:53:32.677 回答
1

不,只要函数的调用者调用free()结构指针成员,它就不会泄漏内存。

记住规则:
调用时会发生内存泄漏malloccalloc并且永远不要调用free相同的地址。只要你这样做,就没有内存泄漏。

请注意,从函数返回动态分配的指针时,指定所有权语义非常重要。简而言之,您的接口应该明确提到在函数调用之后动态分配的指针成员归调用者所有。

既然make_struct()会返回 的副本,那么struct s被它封装的指针会不会泄漏内存而无法释放?

是的,一个结构的副本被返回,但是一个浅拷贝
基本上,这意味着返回的结构副本的指针成员指向的内存位置与 的结构指针成员指向的内存位置相同s
由于两个指针都指向同一个地址,只要调用者调用free返回结构的指针成员,就没有泄漏。

副本本身与动态分配是否有性能成本s

动态分配总是成本高昂且更容易出错。尽可能少地使用它们,除非你真的需要它们,否则不要使用它们。

于 2013-01-22T06:27:22.820 回答