std::move是否使指针无效
Does std::move invalidate pointers?
假设如下:
template<typename Item>
class Pipeline
{
[...]
void connect(OutputSide<Item> first, InputSide<Item> second)
{
Queue<Item> queue;
first.setOutputQueue(&queue);
second.setInputQueue(&queue);
queues.push_back(std::move(queue));
}
[...]
std::vector<Queue<Item> > queues;
};
移动后,指向队列的指针仍在"第一"answers"第二"中工作吗?
std::move是否使指针无效?
没有。一个对象在从中移出后仍然存在,因此指向该对象的任何指针仍然有效。如果Queue
得到了合理的实现,那么从中移出应该会使其处于有效状态(即销毁或重新分配它是安全的);但可能会改变其状态(可能会使其变空)。
移动后,指向队列的指针仍在"第一"answers"第二"中工作吗?
没有。它们将指向已移动的本地对象;如上所述,您不能对移动后对象的状态做出任何假设。
更糟糕的是,当函数返回时,它会被破坏,留下指针。它们现在是无效的,不指向任何对象,使用它们将产生未定义的行为。
也许您希望它们指向已移动到queues
:中的对象
queues.push_back(std::move(queue));
first.setOutputQueue(&queue.back());
second.setInputQueue(&queue.back());
但是,由于queues
是一个向量,当队列下一次重新分配其内存时,这些指针将无效。
要解决此问题,请使用类似deque
或list
的容器,该容器在插入后不会移动其元素。或者,以额外的间接级别为代价,您可以存储(智能)指针而不是对象,正如Danvil的回答中所描述的那样。
指针将不起作用,因为queue
是一个本地对象,将在connect
结束时删除。即使使用std::move
,您仍然可以在新的内存位置创建一个新对象。它将尝试使用尽可能多的"旧"对象。
此外,由于push_back
可能需要重新分配,因此独立于使用std::move
,整个事情根本无法工作。因此,对connect
的调用可能会使所有旧指针失效。
一个可能的解决方案是在堆上创建Queue
对象。以下建议使用C++11:
#include <memory>
template<typename Item>
class Pipeline
{
[...]
void connect(OutputSide<Item> first, InputSide<Item> second)
{
auto queue = std::make_shared<Queue<Item>>();
first.setOutputQueue(queue);
second.setInputQueue(queue);
queues.push_back(queue);
}
[...]
std::vector<std::shared_ptr<Queue<Item>>> queues;
};
其他人提供了很好的详细解释,但你的问题表明你不完全理解move
的功能,也不完全理解它的设计目的。我会用简单的语言来描述它。
顾名思义,move
的意思是移动东西。但是什么是可以移动的呢?一旦对象被分配到某个位置,就不能移动它。回想一下最近添加的新移动构造函数,它类似于复制构造函数。。
所以,这一切都是关于一个对象的"内容"。复制构造函数和移动构造函数都是对"内容"进行操作的。std::move
也是如此。它意味着将一个对象的内容移动到目标中,与copy
相比,它意味着在原始位置不留下任何内容痕迹。
它意味着在任何地方都可以使用,因为有东西迫使我们制作一个我们并不真正关心的副本,我们真的想省略它,并且只在目标位置有内容。
也就是说,使用"move"表示将制作副本,内容将移动到那里并且原始内容将被清除(有时可能会跳过一些步骤,但这仍然是move
的基本思想)。
这清楚地表明,即使原始内容仍然存在,指向原始对象的任何指针都不会指向接收内容的目标。充其量,他们会指向刚刚"清除"的原始内容。最坏的情况是,它会指向一个完全无法使用的东西。
现在看看你的代码。它填充queue
,然后将指针指向原始指针,然后是moves
和queue
。
我希望现在能清楚地知道发生了什么,以及你能做些什么。
- 在 C++ 中传递字符串时指针无效
- free():仅在一种情况下指针无效
- free():实现矢量擦除()时的指针无效
- free():添加字符串时指针无效
- C++ ecliipse free():函数末尾的指针无效
- C++ 指针无效函数问题
- 将 boost::object_pool 与矢量一起使用时指针无效
- free():矢量 C++ 的指针无效<vec4i>
- omnet++free():指针无效,错误134/139
- 在OpenCV中调用stereoRectify会导致异常:帧指针无效
- 销毁和重新创建一个对象会使指向该对象的所有指针无效吗
- 用户定义类中的Null指针无效
- 删除指向类的指针无效
- 运行GTest时指针无效
- C++错误消息:指针无效
- 可以std::string reconfiguration使指向堆的指针无效
- 为什么删除指向指针向量的指针会导致指针无效
- MPI_scatter:缓冲区指针无效
- mmap 错误:分段错误/指针无效错误
- 返回 std::string 时指针无效(libc 如此说)