2010-12-02 73 views
0

我的目標是反覆運行API調用並檢查內存泄漏。
API接受整型輸入並返回一個指向結構鏈表中第一個結構的指針作爲輸出。每個結構可能有其他類型的結構變量。
在下面的代碼中,我試圖表示我的問題。
使用函數作用域到期來釋放結構鏈表的內存

問題出在callApi()函數中。我需要處理由API()返回的結構「輸出」佔用的內存。即使我在這裏使用空閒(輸出),它也會導致內存泄漏,因爲它指向嵌套結構的鏈表。 (信息來源:http://en.wikibooks.org/wiki/C_Programming/Memory_management

問題:當控制熄滅功能的恢復主要 當離開退出callApi()調用,將在「輸出」嵌套結構到期()?它會釋放整個內存嗎?
請建議解決方法來解決這個內存泄漏問題。

Can this problem be overcome with C++?

typedef struct{ 
    int dev_size; 
    char *dev_name; 
    dev_stat *next_dev; 
    mem_stat *mem_info; 
} dev_stat 

typedef struct{ 
    int mem_capacity; 
    char *mem_name; 
} mem_stat 

int main() 
{ 
    int input; 
    int return_val; 
    int callApi(int); 
    while(1) 
    { 
    return_val=callApi(input); 
    print return_val; 
    } 
} 

int callApi(int ip) 
{ 
    //Update: Memory allocation is unnecessary as it is done inside the API() call itself 
    //dev_stat *output=(dev_stat *)calloc(2,sizeof(dev_stat)); 
    int ret_val; 
    ret_val=API(ip,&output); 
    free(output); 
    output=NULL; 
    return ret_val; 
} 
+0

什麼是'int callApi(int);'在你的主要做? – Muggen 2010-12-02 12:56:32

+0

該程序僅用於給出程序流程的總體思路。它不是確切的C語法。使用callApi()的原因:如果我在main()中調用API(),那麼在程序結束之前,所使用的變量將永遠不會超出範圍。因此,在main() – 2010-12-02 13:08:03

回答

4

簡單的答案是,不,內存不會 「過期」 當你退出的功能。

API 應該提供了一種方法來「返回」返回的值,如果它是一個複雜的結構。如果沒有,那麼自行穿越結構並釋放它可能是唯一的出路。

3

第一個問題誰是業主你將要免費的結構。

可能API會返回一個指向其內部結構的指針,您不能釋放它(因爲它可能是共享的)。

也許你的代碼負責釋放結構本身,但不是結構指向的其他結構。這樣您就需要釋放返回的結構並忘記它。

但是,您可能有責任從返回的結構中釋放整個對象樹。在這種情況下,可以預見的是,API有一些功能可以正確地爲其後代分配結構。如果不是(這很可能不是這種情況),則必須遞歸地釋放由結構引用的所有資源。

您應該查看APi文檔以找出哪三種情況是您的情況。


更新:
明確你的情況下(整體結構應手動釋放),我會使用類似的東西:

void free_mem_stat(struct mem_stat* p) 
{ 
    if (!p) return; 
    free(p->mem_name); 
    free(p); 
} 

void free_dev_stat(struct dev_stat* p) 
{ 
    // first, clean up the leaves 
    for(struct dev_stat* curr = p; curr; curr = curr->next_dev) 
    { 
     free(curr->dev_name); 
     free_mem_stat(curr->mem_info); 
    } 
    // than, clean up the linked list 
    for(struct dev_stat* curr = p; curr; /**/) 
    { 
     struct dev_stat* next = curr->next_dev; 
     free(curr); 
     curr = next; 
    } 
} 

int callApi(int ip) 
{ 
    int ret_val; 
    struct dev_stat* output; 
    ret_val = API(ip, &output); 
    free_dev_stat(output); 
    return ret_val; 
} 

注意,像free_dev_stat功能應當由提供API本身,如果API開發人員真的打算讓用戶釋放它們的結構。