在一个函数中,我创建了一个具有大量空间的向量,我推送运行时确定的对象数量Edge
)。但是,其他对象保持指向向量中Edges
的指针。有时整个程序会因为指针变为无效而出现故障,我怀疑当向量达到容量并重新分配时会发生这种情况,从而使内存地址无效。
这有什么办法吗?或者是否有另一种将堆分配组合在一起的解决方案?
注意:这样做的主要动机是最小化堆分配,因为这会降低我的算法速度。最初我有vector<Edge *>
,并且每个添加的元素都是单独分配的。批量分配大大提高了速度,但此处描述的vector
方法使指针无效。
您的代码示例,根据要求: 这是我声明为堆栈var:
的向量vector<Edge> edgeListTemp(1000);
然后我使用rvalue重载添加它:
edgeListTemp.push_back(Edge{edge->movie, first, second});
Node
个对象指向这些:
first->edges.push_back(&edgeListTemp.back());
second->edges.push_back(&edgeListTemp.back());
edges
声明如下:
std::vector<Edge *> edges; /**< Adjacency list */
答案 0 :(得分:2)
有几种可能的解决方案:
reserve
;元素不会被重新分配,直到达到那个大小; std::deque
代替。 std::deque
保证只要你只从正面/背面推/弹,就不会使指向元素的指针无效; std::list
保证永远不会使对元素的引用无效,但它引入了几个严重的性能损失(没有O(1)寻址,每个节点有一个分配); std::shared_ptr
的向量,并始终使用它来保持对元素的引用;这显然有一个缺点,就是根据你的使用情况,需要为每个元素分配一个,这可能是也可能是不可接受的。答案 1 :(得分:1)
std::deque
一旦添加就不会移动元素,因此只要不删除引用的元素,迭代器和引用就是稳定的。
与std::vector
类似,std::deque
提供随机访问迭代器。对双端队列的随机访问比std::vector
慢一点,但仍然是O(1)。如果你需要稳定的参考,那么轻微的减速可能是可以接受的。
或者,您可以保留对向量的引用和向量中的索引,而不是指向元素的指针。