是安全的:V.push_back(V [0]); [英] is that safe: V.push_back( V[0] );

查看:90
本文介绍了是安全的:V.push_back(V [0]);的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚发现,在Visual Studio 8下运行的代码不再运行在9以下,现在我正在寻求确认我的代码是否不安全,只是意外工作或者可以从STL的标准符合实现中得到什么。


基本的是,给定一个带有一些元素的向量V,我想推送其中一个元素,就像这样:

Hi, I just found, that code that ran under Visual Studio 8 doesnt run under 9 anymore and now im seeking confirmation of whether my code is unsafe and just accidentially worked or what one can expect from a standard conforming implementation of STL.

The basic thing is that, given a vector V with some elements in it, I want to push_back one of these elements, like this:

展开 | 选择 | Wrap | 行号

推荐答案

如果向量不是h,当你调用push_back时,问题就出现了ave足够的容量然后它被重新分配,任何重新分配使所有先前获得的迭代器,引用和指针无效。


但是你只是通过V [0]获得了引用,所以如果push_back导致重新分配这个引用立即失效,然后你试图从它复制。


它可能以前工作,因为最近释放的内存仍然挂着相同的值,但访问该内存实际上未定义的行为,这就是它不再工作的原因。

如果你想打电话


V.push_back(V [0]);


你需要绝对确定没有重新分配,或者你需要做一些像


X temp = V [0 ];

V.push_back(temp);


这实际上需要参考V [0]返回的对象的副本,所以它可能是相当的如果这是一个大对象,则效率低下。
Here is the problem, when you call push_back if the vector does not have enough capacity then it gets reallocated and any reallocation invalidates all previously obtained iterators, references and pointers.

However you just got a reference through V[0] so if the push_back causes a reallocation this reference is immediately invalidated, then you tried to copy from it.

It was probably working previously because the recently freed memory was still hanging around with the same values but accessing that memory is actually undefined behavior which is why it is no longer working.

If you want to call

V.push_back(V[0]);

you need to be absolutely certain that there will be no reallocation, alternatively you need to do something like

X temp = V[0];
V.push_back(temp);

This actually takes a copy of the object returned by the reference V[0] so it could be quite inefficient if that is a large object.


ok,我明白。感谢banfa。


关于tmp副本:怎么样


V.reserve(V.size()+ 1);

V.push_back(V [0]);
ok, I understand. thanks banfa.

regarding the tmp copy: what about

V.reserve( V.size()+1 );
V.push_back( V[0] );


这应该有效,因为你确保你至少有足够的内存来执行push_back而不需要重新分配才能调用push_back。


然而更好的是


V.reserve(V.size()* 2);


就在for之前,因为你通过push_back V [0]将每个当前条目的矢量大小加倍,因为这样你可以将重新分配的总数减少到1。
That should work because you have ensured that you have at least enough memory to do the push_back without reallocation before you call the push_back.

However what is even better is

V.reserve( V.size()*2 );

just before the for since you exactly double the size of the vector by push_back V[0] once for each current entry because that way you reduce the total number of reallocations to 1.


这篇关于是安全的:V.push_back(V [0]);的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆