[英]I need to resize an array of pointers
可以說我想調整int指針數組的大小,我有一個看起來像這樣的函數
template<typename T>
static void Resize(T* arr, UINT oldsize, UINT newsize) {
T* ret = new T [newsize];
memcpy(ret, arr, sizeof(arr[0]) * oldsize);
delete[] arr;
arr = ret;
};
當我嘗試調整使用“ new”關鍵字創建的元素數組的大小時,問題就開始出現(即使類中的數據本身是POD),因為delete []會觸發其解構函數,然后該析構函數將新數組留給指針不再存在的對象。 所以..即使對象是用“ new”創建的,我也不能只使用free命令來擺脫舊數組嗎? 或以某種方式刪除數組而不觸發每個成員的解構函數?
使用std::vector
。
編輯 :根據大眾的需求,解釋了為什么OP的代碼不起作用 。
編碼:
template<typename T>
static void Resize(T* arr, UINT oldsize, UINT newsize) {
T* ret = new T [newsize];
memcpy(ret, arr, sizeof(arr[0]) * oldsize);
delete[] arr;
arr = ret;
};
這里arr
是按值傳遞的指針。 最后分配給arr
僅更新實際參數的本地副本。 因此,在此之后,實際參數在調用代碼中指向已delete
d的數組,結果相當災難性!
可以通過引用傳遞該指針來挽救它:
template<typename T>
static void Resize(T*& arr, UINT oldsize, UINT newsize) {
T* ret = new T [newsize];
memcpy(ret, arr, sizeof(arr[0]) * oldsize);
delete[] arr;
arr = ret;
};
但這仍然是非常脆弱的代碼。
例如,調用方需要跟蹤數組大小。
使用名為a
的std::vector
,resize調用看起來像
a.resize( newSize )
與DIY解決方案相反,當newSize
較大時,矢量的那些多余元素將為空(這比將它們保留為不確定的值要安全一些)。
可以像原始數組一樣索引std::vector
。 有關如何使用它的更多詳細信息,請參見C ++教科書 。 如果您還沒有C ++教科書,請閱讀一本:對大多數人來說,從網上的文章和Q / A中學習C ++只是不切實際的主張。
對於它的價值而言,您要嘗試做的並不是一件壞事,有時候它是有道理的,但是new
和delete
(或new[]
和delete[]
提供的接口根本不支持它。 )。 正如其他人所說, 在被支撐malloc
, free
,和realloc
(需要提醒的是realloc
將復制上重新分配的指針值,但不能保證在新區域的指針被初始化為有用的東西,比如NULL
) 。
因此,事不宜遲,幾乎每個人都可以使用的最簡單答案是使用std::vector<int>
而不是嘗試自己管理內存。 向量具有調整大小的能力,當它執行操作時,它將復制需要復制的內容。 存在std::vector
可提供“可調整大小的數組”並為您管理內存。 實際上,如果您想要一個指針容器,最好使用std::vector<std::unique_ptr<T>>
/ std::vector<std::shared_ptr<T>>
(在C ++中) 11)或Boost Pointer Container中的內容 。
就其價值而言,原始STL並未使用new[]
或delete[]
來實現std::vector<T>
。 通常,操作系統提供的內存遠遠超出您的要求。 舉例來說,如果我嘗試malloc
16個字節,我回來了塊很可能是1024個字節。 我可以用它來存儲四個32位整數。 當我空間不足時,我可能會要求32個字節,並獲得另一個1024字節的塊,我可以將我的四個整數復制到該塊中。 但是,當原始塊實際上足夠大以至於開始時,為什么還要麻煩索要一個新塊來容納我的整數呢? 不幸的是, new[]
和delete[]
沒有提供一種方式來表示“給我一個至少這么大的塊,順便說一下,這里的塊可能已經足夠大了”。 realloc
某種功能。 Facebook Folly包含一個不使用new[]
或delete[]
類似std::vector
的容器 (請注意,它也不使用realloc
,因為它通常不適用於對象容器;而是使用malloc
以及非標准函數malloc_usable_size
), Firefox便以類似的方式來管理內存。
即使這樣,我也不鼓勵嘗試變得棘手。 std::vector
有很多滿意的用戶。
我認為在刪除之前使數組中的所有元素都指向NULL應該可以完成這項工作。 但是,如果可以使用STL,則std :: vector將使您的生活更加輕松(如Alf建議的:P)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.