复制具有STL向量类型成员的类的内存

时间:2018-10-09 04:13:55

标签: c++

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

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向量的标头受到某种保护,导致std::memmove()触发未定义的行为?

谢谢!

1 个答案:

答案 0 :(得分:2)

memmove上的reference指出:

  

如果对象不是TriviallyCopyable,则未指定memmove的行为,并且可能未定义

STL向量对象不是简单可复制的对象。

如一个评论中所建议,向量成员函数erase完成了您想要做的事情。

Trivially-copyable对象是以下类的对象:

  
      
  • 每个副本构造函数都很简单或已删除
  •   
  • 每个动作的构造函数都是微不足道的或已删除
  •   
  • 每个副本分配运算符都很简单或已删除
  •   
  • 每个移动分配运算符都很简单或已删除
  •   
  • 未删除至少一个复制构造函数,移动构造函数,复制分配运算符或移动分配运算符
  •   
  • 非删除性毁灭者
  •   
     

这意味着该类没有虚拟函数或虚拟基类。
  TriviallyCopyable对象的标量类型和数组也是TriviallyCopyable的,以及此类类型的const限定(但不是volatile限定)版本。