繁体   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