c++ - 复制具有 STL vector 类型成员的类的内存

标签 c++

对于以下类别的大小为 5 的 vector ,

struct Aclass
{
  double x;
  std::vector<double> y;
  Aclass(){}
  Aclass(double x, int ysize): x(x)
  {
    y.resize(ysize, x * ysize);
  }
};

我想删除第二个元素:

void eraseEle()
{
  std::vector<Aclass> v(5, Aclass(1, 3));


  // Erase the 2nd element
  {
    std::vector<double>(0).swap(v[2].y);
    // Copy the bits from &v[3] ~ &v[5] to &v[2]:
    std::memmove(&v[2], &v[3], sizeof(Aclass) * (v.size() - 3));
    v.resize(v.size() - 1);
  }
  

  // Print
  for(int i = 0, iend = v.size(); i < iend; ++i)
  {
    std::cout << v[i].x << ", " << v[i].y[0] << "\n";
  }
}

方法很不规范。 g++ 4.9.3 -O2 编译它,但程序总是在 std::memmove(...) 处崩溃。是否因为 STL vector 的 header 以某种方式受到保护导致 std::memmove() 触发未定义的行为?

谢谢!

更深入的回答:

未定义行为的原因是 .resize() 释放了 v[4] 中的容器,所以之后,v[3] 包含一个指向任何内容的 vector header ,在访问 vector 元素时引发未定义的行为。要真正让它发挥作用,请添加

std::fill((char*)(&v.back().y), (char*)(&v.back().y) + 24, 0);

v.resize(v.size() - 1); 之前。上面的代码通过让最后一个元素(要删除的)包含一个指向任何内容的 vector 来防止 .resize() 释放容器内存。

最佳答案

referencememmove 上声明:

If the objects are not TriviallyCopyable, the behavior of memmove is not specified and may be undefined

并且 STL vector 对象不是普通可复制对象。

正如一条评论中所建议的那样, vector 成员函数 erase 执行您想要执行的操作。

Trivially-copyable对象是类的对象,其中:

  • Every copy constructor is trivial or deleted
  • Every move constructor is trivial or deleted
  • Every copy assignment operator is trivial or deleted
  • Every move assignment operator is trivial or deleted
  • at least one copy constructor, move constructor, copy assignment operator, or move assignment operator is non-deleted
  • Trivial non-deleted destructor

This implies that the class has no virtual functions or virtual base classes.
Scalar types and arrays of TriviallyCopyable objects are TriviallyCopyable as well, as well as the const-qualified (but not volatile-qualified) versions of such types.

关于c++ - 复制具有 STL vector 类型成员的类的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52713288/

相关文章:

c++ - 使用大数据集加速 postgresql 查询

c++ - 无法使用 OpenCV 打开两个摄像头 - 多线程摄像头读取

c++ - 理解用于实现的 select() 函数

c++ - C++中定义上下文和实例化点之间非依赖构造的解释差异

C++ comp(a,a)==false

c++ - 使用 QuaZIP 将文件夹和内容从 zip 内部复制到另一个位置?

c++ - 如何在 boost::dynamic_bitset<> 中查找第一次和最后一次出现

c++ - C++11 condition_variables 可以用于同步进程吗?

c++ - 如何将包含上标(m²)的字符串转换为普通字符串,如C++中的m2

c++ - 成员变量的类型应该取决于构造函数参数的类型