2014-07-08 34 views
3

我一直想知道.. 根據此表: http://ilay.org/yann/articles/mem/process_map.png(對不起,法國部分) 內存分配在不同的內存空間,這取決於程序的哪一部分正在分配它。在動態加載的庫中,我的內存分配在哪裏?

因此,如果我在我的程序中創建一個對象,它將被分配到程序中。如果動態分配內存,它將位於堆中,而動態加載的對象則是「鏈接」。

我的問題是: 從動態加載的庫中動態分配的內存屬於哪裏?

,如果我有一個包含這個庫:

extern "C" Object* create_Object() 
{ 
    return new Object(); 
} 

class Object 
{ 
    int a; 
    int* b; 
    ... 
} 

請問我的對象在堆或鏈接進行分配?

我的猜測是堆,但我有一段代碼讓我懷疑它。 我正在開發一個Cpp腳本系統,其中我的腳本被編譯爲共享庫,加載到我的程序中,並且每次腳本都需要重新編譯時重新加載。這個想法是在卸載它們之前保存腳本的狀態,並在動態加載的對象的新實例中恢復它們的內容。如果我的動態加載對象的字段被映射到堆中,那麼保存指向數據的指針就足夠了,但是如果創建的類在內存的「鏈接」段中分配,那麼當我恢復內容時,我的指針將指向在未分配的內存,這將使我的程序完全不穩定,這是...

所以我不知道。在內存中的哪裏是我的「對象」實例? 「a」在哪裏,不是動態分配的?如果我動態地分配「b」的內容,在我的例子中?

無論新的被調用的地方在哪裏,我都會期望堆中的新分配,並且Object中的變量a和b也將被分配到堆中,因爲它是從動態分配的對象實例化的,但它只是猜測,我想知道它肯定...

我也想知道我的對象實例一旦我dlclose我的共享庫會發生什麼。再一次,如果它在堆中,我不應該有任何問題來訪問我的對象,但由於我沒有這些符號,我猜這個對象會被分配,但是很不合適,因爲我無法解析它的成員。

我希望你能幫助我與=)

+0

我認爲,除非你重新定義了對象分配器,'new'會在堆上分配。 – rslemos

+0

也許你會在調用這個對象的方法時遇到問題。我不知道C++的內部工作原理,但我希望這個對象有一個指向定義類的指針或其方法的完整表的副本。這些指針將是懸而未決的。當然,這適用於虛擬方法。在Linux上的 – rslemos

回答

1

有沒有這樣的事情從動態加載libaries動態分配的內存。內存動態分配意味着分配給malloc。在你的程序中只有一個malloc,調用它是否來自程序代碼的一部分,這些程序代碼是用原始可執行文件加載的,或者是可共享的目標文件。

注意:從實際角度來看,new通常通過調用malloc來實現,因此,這裏同樣適用。

請注意,在Win32上,情況可能會非常不同:DLL可能有其獨特的malloc(當然還有free)在自己的堆上運行。在這樣的DLL中的內存malloc'd必須在同一個DLL中是free'd。

+0

的實際程序和* .so它調用會共享相同的程序空間嗎?我的意思是,如果我從* .so調用'new'並從主程序中調用'delete'作爲同一個指針,它會起作用嗎? – Chani

+1

是的,只要你不依賴於多態行爲的C++本地實現(包括虛擬析構函數)。正如其他人已經指出的那樣,多態類型的對象將包含一個虛擬函數表的幕後指針。一個類的VFT帶有定義該類構造函數的模塊;因此在模塊卸載時它將被卸載,並且所有的虛擬調用都會導致程序崩潰。 – ach

2

我認爲對象數據安全地存儲在堆上,即使在dlclose()(除非C++動態空間分配器被更改)之後。

但是當然你會遇到調用虛擬方法的問題。虛擬表格將指向不再可用的文本區域。而C++不提供重新綁定虛擬方法的手段;不是我所知道的。

如果你真的需要,您可以:

  1. 改變你的類定義struct;
  2. 將所有虛擬方法聲明爲此結構內的指針;
  3. 你的加載/卸載例程提供綁定(即爲每個分配的對象中的每個指針分配每個實際函數)。

當然,你可以跟蹤所有的對象實例。當然,你可以有一個指針指向一個表格,這個表格本身是由庫提供的;這個單指針仍然必須手動反彈。