我有一个struct和一个函数,它返回一个Foo实例,定义如下:
struct Foo
{
int a;
int* b;
};
struct Foo makeFoo(int a, int bSize)
{
struct Foo foo;
foo.a = a;
foo.b = malloc(sizeof(int) * bSize);
for (int i = 0; i < bSize; ++i)
foo.b[i] = i;
return foo;
}
最初,我认为foo
是一个局部变量,当makeFoo
返回时它会消失,但从这个问题Is it safe to return a struct in C or C++?,我知道这样做是安全的。< / p>
现在我的问题是什么时候会收集foo
的内存?我必须首先free
b
成员吗?
假设我像这样使用makeFoo
:
void barFunc()
{
struct Foo foo = makeFoo(3, 10);
printf("Foo.a = %d;\nFoo.b = [", foo.a);
for (int i = 0; i < 10; ++i)
printf("%d, ", foo.b[i]);
printf("\n");
}
void main(int argc, char* argv)
{
barFunc();
}
当barFunc
返回并且我回到main
时,是否收集了foo
的内存?或者我是否必须在free(foo.b)
结束时致电barFunc
?
答案 0 :(得分:3)
最初,我认为foo是一个局部变量,当makeFoo返回时它会消失,但是从这个问题来看,在C或C ++中返回结构是否安全?我知道这样做是安全的。
你做意识到本地foo
确实已经消失了?按此处返回struct
值只是将其内容复制到调用者提供的实例。(*)
但是,当然,内容包含一个指向您使用malloc()
分配的内存的指针。所以它必须在free()
之后。
(*)这个可以对于小结构来说是一个好主意,取决于你的需要,但总是要记住整个内容被复制 - 它绝对不是你想要的大小结构
答案 1 :(得分:2)
在free(foo.b)
中的foo
变量超出范围之前,您必须自己致电barFunc
。这在makeFoo
函数中不是必需的,因为foo
和指向已分配内存的指针被复制到调用者,所以没问题。
由于您拥有makeFoo
功能,因此最好还拥有deleteFoo
功能:
void deleteFoo(struct Foo *foo)
{
free(foo->b);
}
void barFunc()
{
struct Foo foo = makeFoo(3, 10);
...
deleteFoo(&foo);
}
答案 2 :(得分:-1)
是的从C / C ++函数返回结构是否安全,但是带有大型静态数据的结构struct fooo{int a[1024*1024*1024];};
会导致程序崩溃。因此,为类似的结构返回指向已分配的内存块的指针要安全得多。