2010-07-16 13 views
0

我是C++新手。這對於「新」集合意味着什麼?例如:C++:「新」一個會不斷增長的集合意味着什麼?

UnicodeStringList* tmp = new UnicodeStringList; 
// where UnicodeStringList is typedef to std::list<UnicodeString> 

當你「新」的東西,你必須知道究竟有多大,你需要它是吧?因此,當我使用賦值構造函數複製一個對象時,計算機將如何知道應該在堆上分配多少內存?例如:

*tmp = another_string_list; 

another_string_list被複制到我的new'd UnicodeStringList在堆內存,但我從來沒有最初指定如何之大,堆內存應該是。編譯器不知道有多大的another_string_list是多少內存進入堆?

我很困惑,希望我指定我的問題足以讓一個人可以理解我,但我不知道。

請幫

感謝,

朱利安

+2

我也想問你爲什麼要堆獨立分配一個列表。大多數人只需要使用列表作爲更大對象的一部分,並且由於您可以隨時更改列表的內容,因此很少需要直接堆分配容器。 – Puppy 2010-07-16 18:09:26

回答

0

你可能想看看了做什麼新的。它將它放在堆內存中而不是堆棧內存中。這樣,當你失去範圍時,它不會消失。它與已知尺寸無關。 您可能會將此與數組混淆,其中當您爲數組分配內存時,您需要知道數組的大小,並且通常會將其更新。

+0

是的,我知道它會堆到堆上。我的問題的一部分是:由於我已經告訴它分配堆內存但是將未知大小的對象複製到它中,示例代碼的後果是什麼? – jbu 2010-07-16 17:58:06

5

當你添加元素,它std::list的大小不會改變。我將使用std::vector,因爲該示例更簡單,但適用相同的概念:std::vector包含指向數組的指針,該數組根據需要動態調整大小以包含元素。該指針數組的大小沒有變化(這是一個指針的大小),即使數組它指向的變化

+3

'std :: list'是一個雙向鏈表。一個'std :: vector'會比較適合你的例子。 – zneak 2010-07-16 17:58:41

+0

這個。該列表具有靜態大小,但列表中有許多項目。 – Puppy 2010-07-16 17:59:03

+0

@zneak謝謝;我剛剛編輯了我的答案,說它可能實際上並未使用數組,但我再次將其更改爲僅在示例中使用矢量;那麼確實可以更容易地解釋 – 2010-07-16 18:00:52

1

,你實際上必須知道的東西有多大將是唯一的地方是在棧上。堆棧必須以非常穩定的方式增長,以取悅你的編譯器。然而,這個堆沒有這樣的限制。

當你new東西,你給它分配在堆上。因此,它可以是任何大小。有什麼驚喜,你應該是收集可以被分配在堆棧上。這是因爲不管集合包含什麼,它的大小都是不變的。相反,它包含信息(如指針),堆中的分配大小必須是變體。

3

所有這些「新」的作用是分配足夠的空間存儲所有的成員變量爲您std::list。任何可能需要做的事情是std::list的業務,它應該自己處理(通過它的構造函數和析構函數)。

1

當你new和對象,你會得到所需要的那個對象,在它的初始狀態的記憶。然而,你需要認識到一個類可以在處理其內部狀態方面實現相當複雜的一些。

特別針對你的問題,一個類(在你的情況下是list<>)本身可以在其操作過程中動態分配和釋放內存。這就是你的list集合將會執行的事情 - 當一個項目被添加到列表中時,它將爲該項目分配內存,並且通常使用指針或智能指針對象來執行管理該新項目所需的內務管理。所以內存使用list<>對象可能會改變,但'核心'列表對象本身保持原來分配時的大小。

2

當你「新」的東西,你必須知道究竟有多大,你需要它是吧?

不完全是。至少,不是你想的那樣。

當你的new是一個原始數組的時候,當然你必須提供數組中的元素個數。但是std::list,std::vector,並且這樣的是而不是原始陣列。

std::list爲例:從外部看,您可以將其視爲包含所有內容的東西。但是,詳細地說,它是一個直接包含指針的對象。這些指針指向它在堆上分配的其他對象(使用new)。因此,std::list本身的實例始終是相同的大小,但是當您向其添加更多內容時,它將最終在堆中的其他位置分配更多內容來管理它。

這也是爲什麼你可以使用一個列表作爲堆棧分配的本地變量,並沒有麻煩推入任何數量的項目。

UnicodeStringList MyList; 
MyList.push_back(item1); 
MyList.push_back(item2); 

不需要new。該清單安排自己的內部(堆分配)簿記,以適應我的項目,你想添加到它。

所以當一個列表A分配給列表B.列表A中的所有項目(以及任何內部管理的簿記對象)都被複制到新堆分配項目中,並提供給列表B進行管理。