返回指向本地结构的指针

Posted

技术标签:

【中文标题】返回指向本地结构的指针【英文标题】:Returning pointer to a local structure 【发布时间】:2010-12-01 07:55:46 【问题描述】:

将指针返回到 C 中的本地结构是否安全?我的意思是这样做


struct myStruct* GetStruct()  
  
    struct myStruct *str = (struct myStruct*)malloc(sizeof(struct myStruct));  
    //initialize struct members here  
    return str;
  

安全吗? 谢谢。

【问题讨论】:

不要转换malloc的返回值:c-faq.com/malloc/mallocnocast.html 强制转换 malloc() 的结果可以更容易地将代码移植到 C++,这对于 C 代码来说是很正常的事情。 (是的,我知道 C != C++) 【参考方案1】:

在您的代码中,您没有返回指向本地结构的指针。您正在返回一个指向 malloc() 的缓冲区的指针,该缓冲区将驻留在堆上。

因此,绝对安全。

但是,调用者(或调用者的调用者或调用者的调用者的被调用者,你明白了)将负责调用 free()。

不安全的是:

char *foo() 
     char bar[100];
     // fill bar
     return bar;

因为它返回一个指向堆栈上一块内存的指针——是一个局部变量——并且在返回时,该内存将不再有效。

Tinkertim 指的是“静态分配bar并提供互斥”。

当然:

char *foo() 
    static char bar[100];
    // fill bar
    return bar;

这将起作用,因为它将返回一个指向静态分配的缓冲区条的指针。静态分配意味着 bar 是全局的。

因此,上述内容不会在可能同时调用foo() 的多线程环境中工作。您将需要使用某种同步原语来确保对foo() 的两次调用不会相互干扰。有很多很多可用的同步原语和模式——再加上问题是关于 malloc()ed 缓冲区的事实,这样的讨论超出了这个问题的范围。

要明确:

// this is an allocation on the stack and cannot be safely returned
char bar[100];

// this is just like the above;  don't return it!!
char *bar = alloca(100);

// this is an allocation on the heap and **can** be safely returned, but you gotta free()
malloc(100);

// this is a global or static allocation of which there is only one per app session
// you can return it safely, but you can't write to it from multiple threads without
// dealing with synchronization issues!
static char bar[100];

【讨论】:

+1 ,尽管您可能会考虑通过静态分配 bar[] 并在调用函数时指示需要互斥来将不安全的示例修改为安全的。这将使这个答案在存档中非常有用。 明确一点:malloc 和 new 一样,是在堆中分配空间而不是在堆栈中分配空间?我做对了吗? 谢谢。我时不时地对堆栈和堆感到困惑。 很好的解释,但如果用实际的结构替换数组(并返回指针),也许这些例子会更好,就像问题一样?【参考方案2】:

这样想:如果分配给该指针的内存不是该函数的本地内存(即在该函数的该实例的堆栈帧上 - 准确地说),您可以从该函数返回一个指针

【讨论】:

以上是关于返回指向本地结构的指针的主要内容,如果未能解决你的问题,请参考以下文章

指向结构的指针的元素只返回 0

返回指向结构的指针并访问其字段 C++

返回指向结构数组的指针

使用指向结构数组的指针不会返回完整的数组

有没有办法通过逆向工程来恢复结构。指向该结构的指针由 DLL 中用于导出的唯一函数返回

C++指针问题,请问如何定义一个返回值为结构体指针数组的函数?