在什么情况下STL可以移动向量? [英] Under what circumstances can the STL move a vector?

查看:58
本文介绍了在什么情况下STL可以移动向量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个内存覆盖问题,看起来好像一个向量已经移动了
,即使我没有插入或删除
$中的任何元素b $ b。这可能吗?换句话说,在

中是否存在STL将向量移动向量的情况,或者向量中的元素

无效,如果您不插入或删除元素?


我的实际问题似乎如下:


我有类X,它包含一个STL向量。构造函数确实很少,并且将向量留空。 X没有作业或复制

ctors:


class X {

...

矢量<维布勒> wvec;

};


我还有一堆X',它被保存为矢量。堆上的第一个

项是通过将X推到空的
堆的背面来创建的:


vector<维布勒>&安培; create_heap_item(){

...

heap.push_back(X(...));

返回heap.back()。 wvec;

}


调用''create_heap_item''的例程获取对wvec的引用,

并将其用于将项目插入wvec:


vector< wibble>& wref = create_heap_item();

wref.insert(wreg.begin(),a_wibble);

...


只要

堆上只有一个项目,这一切似乎都能正常工作。但是,当我添加第二个项目时,一切都会出错。我将各种反向迭代器转换成存储在其他类中的第一个wvec,

但是在添加第二个堆项后这些现在似乎指向了

*秒* wvec。这几乎就像第一个wvec已经移动一样。或者我只是搞砸我的参考资料?


有什么想法吗?这让我发疯了......


TIA


Richard

解决方案



Richard Thompson写道:

我有一个内存覆盖问题,看起来好像已经移动了一个向量,即使我没有插入或删除
中的任何元素。这可能吗?换句话说,如果你不插入或删除元素,STL是否会移动一个向量,或者将迭代器无效到向量中的元素
,是否有任何情况?

我的实际问题似乎如下:

我有类X,它包含一个STL向量。构造函数确实很少,并且将向量留空。 X没有作业或副本
ctors:

X类{
...
向量< wibble> wvec;
};

我还有一堆X',它被保存为矢量。堆上的第一个
项是通过将X推到
空堆的后面来创建的:

vector< wibble>& create_heap_item(){
...
heap.push_back(X(...));
返回heap.back()。wvec;
}
<调用''create_heap_item''的例程获取对wvec的引用,
并使用它将项目插入到wvec中:

vector< wibble>& wref = create_heap_item();
wref.insert(wreg.begin(),a_wibble);
...

这一切似乎都有效,只要有''
堆上只有一个项目。但是,当我添加第二个项目时,一切都会出错。 I
将各种反向迭代器放入存储在其他
类中的第一个wvec中,但在添加第二个堆项后,这些现在似乎指向了* second * wvec。这几乎就像第一个wvec已经移动一样。或者我是
我只是搞砸了我的参考资料?



最好不要存储迭代器以备将来使用,因为很可能它们会变得无效(即使你没有't *直接*修改

源向量)。这在你当前的问题中有所说明。


当你把东西推到''堆''时,''堆''矢量可以移动东西

左右(即使你没有触及第一个元素)。所以你的第一个''X''对象可能已被移动到其他地方,因此任何迭代器

的任何成员都变得无效。


一种解决方案是将''heap''中的元素索引存储到

''wref''向量中(而不是存储迭代器)。可能还有其他

解决方案,但这取决于你究竟要做什么。


希望这会有所帮助,

-shez-

任何想法?这让我发疯了......

TIA

Richard






" Richard Thompson"写道:

我有一个内存覆盖问题,它看起来好像已经移动了一个向量,即使我没有插入或删除任何它中的元素。这可能吗?换句话说,如果你不插入或删除元素,那么STL中是否有任何情况会移动一个向量,或者将迭代器无效为向量中的元素



当你将push_back转换为向量时,可能没有足够的空间,可能会移动

向量,并且迭代器可能会失效。

我的实际问题似乎如下:

我有类X,它包含一个STL向量。构造函数确实很少,并且将向量留空。 X没有作业或副本
ctors:

X类{
...
向量< wibble> wvec;
};


X确实有一个副本构造函数和operator =() - 它们被隐式声明为

,除非你告诉编译器。如果你不想要它们

可用,请将它们声明为私有并且不要定义它们:


class X {

private:

X(const& X); //声明但未定义

void operator =(const& X); //声明但未定义

....

};

我还有一堆X',它被维护作为矢量。堆上的第一个
项是通过将X推到空堆的背面来创建的:

向量< wibble>& create_heap_item(){
...
heap.push_back(X(...));
返回heap.back()。wvec;
}


矢量是静态还是全局变量?如果没有,你还有什么回复

参考?如果向量是create_heap_item的本地向量,则返回

a对局部变量的引用 - 即悬空引用。

调用''create_heap_item''的例程获取对wvec的引用,
并使用它将项目插入到wvec中:

vector< wibble>& wref = create_heap_item();
wref.insert(wreg.begin(),a_wibble);


插入使所有迭代器无效到wref。

...

这一切似乎都有效,只要有'
堆上只有一个项目。但是,当我添加第二个项目时,一切都会出错。


理论上,当你添加第二个项目时,所有迭代器可能都是无效的
。通常情况下,我认为这会导致发生这种情况不止一次。

我有各种反向迭代器进入第一个wvec存储在其他类中,但是在添加第二个堆项后,这些现在似乎指向了
* second * wvec。这几乎就像第一个wvec已经移动一样。或者我只是弄乱了我的推荐?




你没有提供足够的信息。可能是你正在使用悬空

引用,或者你通过插入或

push_backs使你的迭代器无效。给一个简短的独立,可编辑的代码片段

重复问题,有人可以帮助你。


祝你好运,


Tom


文章< 8n ****************** **************@4ax.com> ;,

Richard Thompson< no **** @ nospam.com>写道:

只要
堆上只有一个项目,这一切似乎都能正常工作。但是,当我添加第二个项目时,一切都会出错。我将各种反向迭代器放入存储在其他类中的第一个wvec中,但是在添加第二个堆项后,这些现在似乎指向了* second * wvec。这几乎就像第一个wvec已经移动一样。或者我只是弄乱了我的引用?




允许向量重新分配(从而使未完成的

迭代器无效,指针和引用)当size()有可能超过

capacity()时。您可以使用reserve()来设置容量(),从而在需要重新分配时选择




-Howard


I''ve got a memory overwrite problem, and it looks as if a vector has
been moved, even though I haven''t inserted or deleted any elements in
it. Is this possible? In other words, are there any circumstances in
which the STL will move a vector, or invalidate iterators to elements
in the vector, if you don''t insert or remove elements?

My actual problem seems to be as follows:

I have class X, which contains an STL vector. The constructor does
very little, and leaves the vector empty. X has no assignment or copy
ctors:

class X {
...
vector<wibble> wvec;
};

I also have a heap of X''s, which is maintained as a vector. The first
item on the heap is created by pushing an X onto the back of the empty
heap:

vector<wibble>& create_heap_item() {
...
heap.push_back(X(...));
return heap.back().wvec;
}

The routine which calls ''create_heap_item'' gets a reference to wvec,
and uses it to insert items into wvec:

vector<wibble>& wref = create_heap_item();
wref.insert(wreg.begin(), a_wibble);
...

This all seems to work Ok as long as there''s only one item on the
heap. However, when I add a second item, everything goes wrong. I have
various reverse iterators into the first wvec stored in other classes,
but after adding the second heap item these now appear to point into
the *second* wvec. It''s almost as if the first wvec has moved. Or am I
just messing up my references?

Any ideas? This is driving me crazy...

TIA

Richard

解决方案


Richard Thompson wrote:

I''ve got a memory overwrite problem, and it looks as if a vector has
been moved, even though I haven''t inserted or deleted any elements in
it. Is this possible? In other words, are there any circumstances in
which the STL will move a vector, or invalidate iterators to elements
in the vector, if you don''t insert or remove elements?

My actual problem seems to be as follows:

I have class X, which contains an STL vector. The constructor does
very little, and leaves the vector empty. X has no assignment or copy
ctors:

class X {
...
vector<wibble> wvec;
};

I also have a heap of X''s, which is maintained as a vector. The first
item on the heap is created by pushing an X onto the back of the empty heap:

vector<wibble>& create_heap_item() {
...
heap.push_back(X(...));
return heap.back().wvec;
}

The routine which calls ''create_heap_item'' gets a reference to wvec,
and uses it to insert items into wvec:

vector<wibble>& wref = create_heap_item();
wref.insert(wreg.begin(), a_wibble);
...

This all seems to work Ok as long as there''s only one item on the
heap. However, when I add a second item, everything goes wrong. I have various reverse iterators into the first wvec stored in other classes, but after adding the second heap item these now appear to point into
the *second* wvec. It''s almost as if the first wvec has moved. Or am I just messing up my references?

It is best not to store iterators for future use, as it is very likely
that they will become invalid (even if you don''t *directly* modify the
source vector). This is illustrated in your current problem.

When you push something to ''heap'', the ''heap'' vector can move things
around (even though you did not touch the first element). So your
first ''X'' object was probably moved somewhere else, hence any iterators
for any of its members becomes invalid.

One solution is to store the index of elements in ''heap'' into the
''wref'' vector (instead of storing the iterators). There may be other
solutions, but that depends on what exactly you are trying to do.

Hope this helps,
-shez-

Any ideas? This is driving me crazy...

TIA

Richard





"Richard Thompson" wrote:

I''ve got a memory overwrite problem, and it looks as if a vector has
been moved, even though I haven''t inserted or deleted any elements in
it. Is this possible? In other words, are there any circumstances in
which the STL will move a vector, or invalidate iterators to elements
in the vector, if you don''t insert or remove elements?
When you push_back into a vector, there may be insufficient space, the
vector may be moved, and iterators may be invalidated.

My actual problem seems to be as follows:

I have class X, which contains an STL vector. The constructor does
very little, and leaves the vector empty. X has no assignment or copy
ctors:

class X {
...
vector<wibble> wvec;
};
X does have a copy constructors and operator=() - they''re declared
implicitly unless you tell the compiler otherwise. If you don''t want them
available, declare them as private and don''t define them:

class X {
private:
X(const& X); // declared but not defined
void operator=(const& X); // declared but not defined
....
};

I also have a heap of X''s, which is maintained as a vector. The first
item on the heap is created by pushing an X onto the back of the empty
heap:

vector<wibble>& create_heap_item() {
...
heap.push_back(X(...));
return heap.back().wvec;
}
Is the vector static or a global variable? If not, what are you returning a
reference to? If the vector is local to create_heap_item, you''re returning
a reference to a local variable - i.e., a dangling reference.

The routine which calls ''create_heap_item'' gets a reference to wvec,
and uses it to insert items into wvec:

vector<wibble>& wref = create_heap_item();
wref.insert(wreg.begin(), a_wibble);
That insert invalidates all iterators to wref.
...

This all seems to work Ok as long as there''s only one item on the
heap. However, when I add a second item, everything goes wrong.
Theoretically, when you add the second item, all the iterators may be
invalidated. Usually, I would expect it would take more than a single
addition to cause that to happen, though.
I have
various reverse iterators into the first wvec stored in other classes,
but after adding the second heap item these now appear to point into
the *second* wvec. It''s almost as if the first wvec has moved. Or am I
just messing up my references?



You don''t give enough info. It may be that you''re using dangling
references, or that you''re invalidating your iterators by inserts or
push_backs. Give a short stand-alone, compilable piece of code that
duplicates the problem and someone can probably help you.

Best regards,

Tom


In article <8n********************************@4ax.com>,
Richard Thompson <no****@nospam.com> wrote:

This all seems to work Ok as long as there''s only one item on the
heap. However, when I add a second item, everything goes wrong. I have
various reverse iterators into the first wvec stored in other classes,
but after adding the second heap item these now appear to point into
the *second* wvec. It''s almost as if the first wvec has moved. Or am I
just messing up my references?



A vector is allowed to reallocate (and thus invalidate outstanding
iterators, pointers and references) when size() threatens to exceed
capacity(). You can use reserve() to set capacity() and thus choose
when you want the reallocation to happen.

-Howard


这篇关于在什么情况下STL可以移动向量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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