2009-09-25 91 views
4

將指針返回到C中的本地結構是否安全?我的意思是這樣做返回指向本地結構的指針


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

安全嗎?
謝謝。

+1

不要施加'malloc'的返回值:http://c-faq.com/malloc/mallocnocast.html – 2009-09-25 07:28:48

+1

投射malloc()的結果可以讓它更容易將代碼移植到C++,這對於C代碼來說是非常正常的事情。 (是的,我知道C!= C++) – ahy1 2009-09-25 12:04:13

回答

13

在您的代碼中,您沒有返回指向本地結構的指針。您正在返回一個指向將駐留在堆上的malloc()的緩衝區的指針。

因此,絕對安全。

但是,調用者(或調用者的調用者或調用者的調用者的被調用者,你會明白)將負責調用free()。

什麼是不安全的是:

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

由於它返回一個指針的內存塊是在棧上 - 是一個局部變量 - 和,在返回時,該內存將不再有效。

Tinkertim提到「靜態分配欄和提供互斥」。

肯定的:

char *foo() { 
    static char bar[100]; 
    // fill bar 
    return 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]; 
+0

+1,儘管您可能會考慮通過靜態分配bar []來修改不安全的示例以保證安全,並且在調用函數時指示需要互斥。這將使這個答案在檔案中非常有用。 – 2009-09-25 06:03:11

+0

要明確一點:malloc和new一樣,在堆中分配空間而不是堆棧?我是否正確? – Amarghosh 2009-09-25 06:05:48

+0

謝謝。我一時混淆堆棧和堆。 – 2009-09-25 06:08:48

2

認爲它是這樣的:你可以從一個函數返回一個指針,如果分配給該指針的內存是不是局部的功能(即該堆棧幀精確)