簡體   English   中英

C ++中的釋放(指針向量數組)

[英]Deallocation in C++ (Array of Vector of Pointers)

好吧,所以我正在創建一個Graph類,我希望能夠運行算法,並且可能在今年夏天有空閑時添加一個gui。 現在我有一個adjList,它實現為一個向量數組(每個頂點一個),每個向量是一個指針列表,表示從每個相關頂點到其他頂點的邊。 它被聲明為我的Graph類的受保護成員,如下所示:

std::vector <Node*> *adjList;
adjList = new std::vector<Node*>[V];

我有一個附帶問題。 現在我在這里有一個包含指針的向量數組(通過指針)。 如果相反,這不是一個數組,而是指向一個節點指針的單個向量的指針,那么我可以像這樣調用構造函數:

adjList = new std::vector<Node*>(10);

這將允許我為向量中的動態數組指定默認大小,但似乎我無法調用構造函數,或者至少在我有數組時無法正確獲取語法。

現在主要關注我。 對於我的指針數組中的每個向量,我在addVertex方法中使用對new運算符的調用為每個向量添加了許多節點指針。 現在我需要確保正確處理所有這些的釋放。 我相信我已經理解了它應該如何在C ++中運行,但是我知道指針很棘手,所以我想讓別人看看我在這個代碼庫中添加批量之前。 我找不到任何與我所擁有的搜索相似的內容。 這是我的釋放:

for(int i =0; i < V; i++)
    for (unsigned int j = 0; j < adjList[i].size(); j++)
        delete adjList[i][j];
delete adjList;

這將釋放所有的內存。 還有一種簡單的方法讓我可以肯定地驗證這一點,例如。 在我調試的時候,要記住使用new分配了多少內存?

[編輯:更新w / more info]

以下是Google圖書的鏈接 ,其中顯示了我想要在psuedocode中實現的算法之一。 此版本的廣度優先搜索在鄰接列表(指針列表數組)上運行。 必須使用指針,因為使用鄰接列表分配給每個節點的屬性。

我希望在運行后保存存儲到每個節點的BFS算法中的這些屬性。 我知道可以通過其他方式執行此操作,可能是索引節點並使用並行數組來存儲屬性。 但我希望代碼與此偽代碼類似(對於鏈接中的BFS)。

  1. 你為什么使用一組向量?
  2. 為什么要保持指向矢量的指針?
  3. 你為什么要保持一個指針向量?

所有這三個決策都會花費你並直接否定向量類的內存管理能力。 向量不僅僅是一個可以在封面下成長的數組,它還通過稱為RAII的模式為您管理內存。

當您創建指針向量時,向量無法清除指針在銷毀時引用的內存,因此您仍需要在向量的每個元素上調用delete

當您創建指向向量的指針時,您無法利用向量釋放它在析構函數中分配的任何內存這一事實。 因此,再一次,你否定了向量管理內存的能力,因為你必須在向量上調用delete以防止內存泄漏。

當你維護一個向量數組時......你已經在使用向量了,為什么不使用vector<vector<T>>

向量類型在幕后為您動態分配內存,專門用於避免您現在遇到的問題。 當然,你可以管理你自己的記憶(你只需按照你所分配的相反順序解除分配,你似乎已經掌握了),但是為什么還有機制來為你做這件事呢?

我不明白這里的設計目標。 為什么不簡單地使用vector<vector<Edge>>並完全擺脫這些問題呢?

class Edge {
    // whatever
}

class Graph {
private:
    // when instances of this class go out of scope, 
    // all of the memory allocated to these vectors is deallocated for you!
    vector<vector<Edge>> vertices;  
}

如果您正在構建有很多索引通過指針內部對象類,一種方式,以確保您的存儲位置刪除對象只有一次是保持一個內存池。 例如,您可以擁有一個std::vector<Node*> Graph::memPool成員。 刪除Graph ,只需刪除Graph::memPool所有內容,而不刪除單個節點的adjList的索引。 無論何時創建新節點,只需將其添加到內存池即可。

在當前示例中,如果兩個節點具有同一節點的邊緣,則可以刪除無效的內存位置。

另一種方法是使用編號索引而不是指針。 該圖具有節點的主矢量,而每個節點中的鄰接列表保持矢量索引。

class Graph
{
    std::vector<Node> all_nodes;
    ...
};

struct Node
{
    std::vector<size_t> adjList;
    SomeDataType nodeData;//e.g. node cost, weight, reward, etc
    ...
};

在這種情況下,不需要明確的解除定位。 與使用指針類似,從圖中刪除節點將需要掃描鄰接列表以更新索引。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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