C:包含动态分配成员的结构的范围?

时间:2015-10-20 00:04:20

标签: c struct scope dynamic-memory-allocation

我有一个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

3 个答案:

答案 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];};会导致程序崩溃。因此,为类似的结构返回指向已分配的内存块的指针要安全得多。