簡體   English   中英

我需要調整指針數組的大小

[英]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;
};

但這仍然是非常脆弱的代碼。

例如,調用方需要跟蹤數組大小。

使用名為astd::vector ,resize調用看起來像

a.resize( newSize )

與DIY解決方案相反,當newSize較大時,矢量的那些多余元素將為空(這比將它們保留為不確定的值要安全一些)。

可以像原始數組一樣索引std::vector 有關如何使用它的更多詳細信息,請參見C ++教科書 如果您還沒有C ++教科書,請閱讀一本:對大多數人來說,從網上的文章和Q / A中學習C ++只是不切實際的主張。

對於它的價值而言,您要嘗試做的並不是一件壞事,有時候它是有道理的,但是newdelete (或new[]delete[]提供的接口根本不支持它。 )。 正如其他人所說, 被支撐mallocfree ,和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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM