繁体   English   中英

std :: vector指针可靠吗?

[英]Is a std::vector pointer reliable?

说我有这个:

Object *myObject;
std::vector<Object> objects(99);

....
myObject = &objects[4];

可以安全地假设myObject的指针将始终有效,无论有多少大的object [],如果我删除了一些对象,只要我从不擦除myObject指向的实际对象,就可以了吗? 还是不同地工作? 如果上述方法不起作用,我还能怎么实现呢? 这是因为在我的设计中,我希望孩子有一个指向其父对象的指针,该指针是在添加孩子时由父对象分配的,但是父对象位于std :: vector中,我需要随机访问。 在我看来,std :: list会更好吗?

谢谢

不,假设绝对不安全。

该标准说明了将/不会使标准容器上的迭代器无效的内容; 每当向量迭代器失效时,指向它的指针也将变为无效。 实际上,这意味着当向量调整大小时(包括在调用push_back()时隐式包含),指向该向量的任何迭代器都会失效,指针也将无效。 同样,在调用被擦除的项之后,调用erase()将使指针无效,因为它们都必须向上移动以填充被擦除的空间。

一个std::list会更好; 您可以并行维护指向项目的指针向量,这将使您可以通过索引访问它们,而无需在内存中移动它们。

如果向量填满了分配的空间,而您尝试插入更多空间,则需要重新分配其存储,这将涉及复制对象并破坏旧的存储,这将使您保留的指针无效-因此不,这还不够好。

std :: list可以正常工作,因为它不依赖于连续存储,但是您失去了进行快速随机访问的能力。 另外,您可以在集合中存储指向对象的指针,在这种情况下,您可以删除该元素,并且指针将一直有效,直到您在代码中释放该内存为止-但您需要在某个时候自行处理。

另一个选择可能是双端队列 尽管双端队列迭代器被push_back无效,但对元素的直接引用(例如您在此处使用的指针)仍然有效。

如果向量保持相同大小,则可以通过在声明它之后或通过(如您所进行的)声明初始数量的元素(每个构造为具有默认元素值reserve()的最大数量的元素来调用reserve()来保证这一点。 。

如果删除或添加元素,则可以随时重新分配基础存储。

由于您在此处使用原始指针,因此可以将NULL用作“空元素”标志,以保持存储不变。 由于您最初将其设置为99,因此之后它们都将为NULL(任何指针作为矢量元素的默认值),并且reserve是多余的,除非您打算扩展列表。

一个让您不必担心向量存储的选项是将元素存储为boost::shared_ptr<Object> 然后,如果没有其他人使用vector元素,则仅deletedelete实际上delete引用的Object实例。

boost::shared_ptr<Object> myObject;
std::vector<boost::shared_ptr<Object> > objects(99);

myObject = &objects[4];

objects.clear();
// myObject still valid since Object instance referenced thru shared_ptr

奇怪,但是没有人提到boost :: stable_vector事情:

...只要未擦除稳定元素的元素的引用和迭代器就一直有效,并且分配了end()返回值的迭代器始终保持有效,直到关联的稳定向量被破坏为止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM