在矢量std :: move之后,矢量元素如何保留其原始地址?

Vas*_*lis 6 c++ vector move-semantics c++11

正如您在输出中看到的那样,向量的对象pre不仅"移动"到向量post,还将其原始地址空间保留在内存中.这一举动背后的真实情况是什么?这种行为有望吗?假设我需要有一个指向这些对象的单独指针向量,可以安全地假设在此移动之后对象将始终具有其原始地址吗?

实际上,我有一个类包含这样的向量和我作为成员提到的指针向量.我还删除了副本ctors,并为课程定义了移动副本.

#include <iostream>
#include <vector>

struct B {
    int val = 0;   
    B(int aInt) : val(aInt) {  };
};

int main() {

    std::vector<B> pre;

    pre.push_back(B(1));
    pre.push_back(B(2));
    std::cout << "pre-move:\t" << (void*)&pre.at(0) << '\n';
    std::cout << "pre-move:\t" << (void*)&pre.at(1) << '\n';

    std::vector<B> post(std::move(pre));

    std::cout << "post-move:\t" << (void*)&post.at(0) << '\n';
    std::cout << "post-move:\t" << (void*)&post.at(1) << '\n';

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

pre-move:   0x1d7b150 
pre-move:   0x1d7b154 <------|
post-move:  0x1d7b150        |
post-move:  0x1d7b154 <------|
Run Code Online (Sandbox Code Playgroud)

Som*_*ude 11

向量基本上只是指向堆分配内存的指针,当前长度和向量的当前容量.

通过"移动"向量,您所做的只是复制这些值,并重置移动向量的值.

对于矢量的数据,它基本上相当于

original_pointer = some_place_in_memory;
new_pointer = original_pointer;   // Copies the *value* of original_pointer
original_pointer = nullptr;
Run Code Online (Sandbox Code Playgroud)

无需分配新内存并复制向量中的数据.

  • 看看手册显然可以依赖*除非*源和目标有不同的分配器,在这种情况下所有元素都被*单独移动*:https://en.cppreference.com/w/cpp/container/vector/operator %3D可能值得添加此信息,因为它是问题的一部分. (3认同)
  • 但是当使用`push_back`时,要向向量添加元素,所有元素的地址都会发生变化!这是由于向量的设计使其元素在内存中连续,因此它将它们复制到另一个(更大的)地址空间? (2认同)