[英]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)。
所有这三个决策都会花费你并直接否定向量类的内存管理能力。 向量不仅仅是一个可以在封面下成长的数组,它还通过称为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.