设置迭代器因移动语义失效
Set iterator invalidated by move semantic
我有以下不可变的容器类(公共访问values
只是为了简单起见(:
struct Container
{
std::unordered_set<int> values;
//Default constructor
Container() = default;
//Copy constructor
Container(const Container& other)
: values(other.values)
{ }
//Move constructor
Container(const Container&& other)
: values(std::move(other.values))
{ }
Container RemoveValue(int value) const
{
//Create a copy of this object
Container copy(*this);
//Remove one element from the copy
copy.values.erase(value);
return copy;
}
};
此容器包含一组值。该方法RemoveValue()
返回已删除特定值的当前对象的副本。为此结构定义了适当的移动构造函数。
我按如下方式使用此容器:
int main()
{
std::vector<Container> containers;
{
//Initialization
Container initialContainer;
initialContainer.values.insert(1);
initialContainer.values.insert(2);
containers.push_back(std::move(initialContainer));
}
const Container* currentContainer = &containers.front();
for (int value : currentContainer->values)
{
Container newContainer = currentContainer->RemoveValue(value);
//Do some checks, then...
containers.push_back(std::move(newContainer));
}
std::cout << containers.size() << std::endl;
return 0;
}
我用单个容器(值为 1 和 2(初始化容器向量。然后,我获取指向此初始元素的指针并迭代每个值。对于每个值,我调用RemoveValue()
并将生成的容器插入到向量中。
在 gcc 中,这似乎工作得很好。但是,我在Visual Studio 2015中收到运行时错误。
在调试模式下,错误为:"列表迭代器不可增量"。此错误发生在 for (int value : currentContainer->values)
处的第一次迭代之后(当迭代器要递增时(。
释放模式下,错误为:"在位置 0x38 处访问违规读取"。此错误发生在 RemoveValue
中的 copy.values.erase(value)
处。但仅限于第二次迭代。令人惊讶的是,此时values
不再包含元素(size()
返回 0(。
我不明白这些错误中的任何一个。如何解决这些问题?
C++命令行管理程序示例也运行时没有错误。但是,它输出2
作为最终数量的容器,而我预计有三个(初始容器,一个删除了1
,一个删除了2
(。
currentContainer
是指向向量containers
元素的指针。循环体通过调用push_back
来修改containers
。这可能会使指向矢量的指针无效,如果是这样,currentContainer
最终可能会指向垃圾。
通常,不要使用指向std::vector
中保存的对象的指针。相反,请使用containers.front()
或containers[0]
来获取第一个元素。
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- Boost Spirit,获取迭代器内部语义动作
- 可以使用移动语义更改或改进此C++代码吗?
- c++在使用指针时移动语义
- 不明白迭代器,引用和指针失效,一个例子
- 在C++17中,引用const字符串的语义应该是什么
- Xcode 语义问题引用或以前定义的代码
- 使用移动和复制语义时函数匹配如何工作?
- C++,您能否设计一种数据结构,将指针保存在连续内存中并且不会使它们失效?
- std::unordered_map::提取引用/指针失效
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 移动语义和深层/浅层复制之间有什么关系?
- 了解构造函数在移动、复制、赋值语义中的行为
- std::unique_lock移动语义
- 移动语义和运算符 + 重载
- C++ 移动语义是否在任何情况下都能节省资源?
- 移动语义在这里如何工作?
- 使用移动语义:右值引用作为方法参数
- 设置迭代器因移动语义失效