2011-07-18 33 views
1

假設func函數有錯誤,以至於它泄漏內存。關於在子進程中發生內存泄漏的問題

pid_t childPid; 
int status; 
childPid = fork(); 
if (childPid == -1) 
    errExit("fork"); 
if (childPid == 0) /* Child calls func() and */ 
    exit(func(arg)); /* uses return value as exit status */ 

/* Parent waits for child to terminate. It can determine the 
    result of func() by inspecting 'status'. */ 
if (wait(&status) == -1) 
    errExit("wait"); 

問題1> 如果一個程序到底泄漏內存,程序退出後,它仍泄漏內存或系統將收集由程序分配的所有內存並沒有更多的泄漏內存?

問題2> 父進程調用等待後,子進程中的func是如何引起泄漏的內存?

回答

6

如果程序出現內存泄漏,最終退出程序後,不是 還是泄漏內存或系統將收集由 程序分配的所有內存,有沒有更多的泄漏內存?

系統將收集來自子進程的所有內存資源,並且子進程中不再有任何泄漏的內存。此外,調用fork()將分離父代和子代的內存空間,因此子進程中的泄漏不會在父進程中泄漏,除非您在兩者中調用相同的越野車功能。

父進程調用等待後,子進程中的func如何導致泄漏內存 ?

在父母中調用wait(),並且子程序泄漏內存確實沒有任何相互之間的任何關係。父母對wait()的調用僅導致父母阻止等待指示子過程已完成的信號。在完成之前,孩子仍然必須先致電func(),因爲它必須將返回值func()傳遞給exit()。因此,即使在調用func()後幾乎立即發生操作系統的清理操作,因此func()仍然可以在技術上「泄漏」內存,因爲它會在堆上分配一些內存,但不會清理內存。換句話說,在完成對exit()的調用之後,操作系統已經釋放了孩子使用的資源,但是func()本身仍然可能無法釋放它嘗試分配的任何內存。

3

任何現代操作系統都不允許子進程(或任何進程)在終止後離開系統處於不一致狀態。

如果該功能是越野車,因爲它會導致分段錯誤意識,操作系統通常會與信號SIGSEGV之後的進攻和家長將通過wait孩子已與退出承認殺死進程一個信號,通常不會。

3

內存泄漏只是一種資源泄漏。

分配給例如malloc()的內存頁面被稱爲「專用頁面」,因爲它們只屬於一個進程(它們可能是寫入時複製與父代或子代共享的,但它們仍然是它自己的頁)。

但是,還有很多其他泄漏資源的方式。某些類型的共享對象不會自動清理;文件系統中的文件將不會自動清理,您的孩子創建的子進程在退出時也不會自動獲得。

+0

當前子進程死亡時,任何由當前子進程產生的新子進程都不會被獲得,但是他們的父進程會從現在已死的子進程切換到init進程,然後調用'等待()'爲其所有的孩子。因此,在某些時候,那些產生的子進程在他們調用'exit()'...時,如果不是由它們的父節點,然後由'init'調用,將會被適當地清除。這就是說,雖然他們正在運行,即使父母是'init',他們仍然會繼續消耗資源,所以我同意這是一種「泄漏」的替代類型。 – Jason