如何解决在严格的上下文中:是否可以安全使用指向容器元素的指针?
在下面的代码中,我用来自另一个容器m
的元素填充地图vv
。我正在使用指向地图中当前元素的指针,并且正在对该元素/对象进行进一步的操作。
struct obj_t { vector<int> w1,w2,w3,... };
map<int,obj_t> m;
vector<vector<int> vv;
for (vector<int> &v : vv) {
obj_t *p = &m[v[0]]; // create entry at key = v[0] if none existed
p->w1.push_back(v[1]);
p->w2.push_back(v[2]);
// many fields w3,w4,... so using pointer may be "efficient"
}
问题:此指针访问安全吗? m
中正在被操纵的元素是否保证在循环内通过每次访问都保留其地址 ?从一个迭代到另一个? (尽管在此示例中不是必需的。)
我知道您通常不应使用指向容器中元素的指针,因为这些元素可能会被“程序” /“运行时”的其他部分移动。但是我猜想,在像这样的紧密上下文中,不会对映射m
进行其他任何操作,这样的指针访问就可以保证是安全的。正确吗?
怀疑可能不是这样,例如some_large_allocation()
可能导致操作系统将内存对象重定位:
for (vector<int> &v : vv) {
obj_t *p = &m[v[0]]; // creates entry at key = v[0] if none existed.
p->w1.push_back(v[1]);
// some_large_allocation() // can force elements of m to be relocated?
p->w2.push_back(v[2]); // *illegal* m and/or the element pointed to was moved
...
}
更新(在此处编写,因为标记为“欺骗”,所以未找到答案)
对于这个问题Pointers to elements of STL containers,可接受的答案为:
std :: list,std :: set和std :: map保证迭代器 (包括简单指针)在新元素出现时不会失效 被添加,甚至被删除。
解决方法
我了解您通常不应使用指向容器中元素的指针,因为这些指针可能会被“程序” /“运行时”的其他部分移动。
...
怀疑可能不是这样,例如
some_large_allocation()
可能导致操作系统将内存对象重定位
您可能会想到更多类似Java的“托管”语言,它们可以根据需要自由移动内存(但也会更新对该内存的引用,因此程序员无需担心)。 C ++不会执行任何操作。
在C ++中,仅当以某些方式修改容器(取决于容器)时,指向容器中元素的指针才无效。例如,对于std::vector
,只要向量不需要重新分配,使用指向其元素的指针是安全的。对于std::map
,指向映射中元素的指针永远不会无效(当然,只要元素保留在映射中即可)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。