微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在严格的上下文中:是否可以安全使用指向容器元素的指针?

如何解决在严格的上下文中:是否可以安全使用指向容器元素的指针?

在下面的代码中,我用来自另一个容器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 举报,一经查实,本站将立刻删除。