具有 STL 向量类型成员的类的复制内存
Copy memory of a class with STL vector type member
对于下一个类的大小为 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()
触发未定义的行为吗?
谢谢!
更深层次的答案:
未定义行为的原因是.resize()
在v[4]
中释放容器,因此之后,v[3]
包含一个不指向任何内容的vector
标头,在访问向量元素时引发未定义的行为。要真正使其正常工作,请添加
std::fill((char*)(&v.back().y), (char*)(&v.back().y) + 24, 0);
在v.resize(v.size() - 1);
之前.上面通过让最后一个元素(要擦除(包含不指向任何内容的vector
来防止.resize()
释放容器内存。
关于memmove
的参考资料指出:
如果对象不是 TriviallyCopyable,则未指定 memmove 的行为,并且可能未定义
STL 矢量对象不是一个简单可复制的对象。
正如一条评论中所建议的,向量成员函数erase
执行您想要执行的操作。
可简单复制的对象是类的对象,其中:
- 每个复制构造函数都是微不足道的或删除
的- 每个移动构造函数都是微不足道或删除
的- 每个复制赋值运算符都是微不足道的或删除
的- 每个移动分配运算符都是微不足道或删除的
至少一个复制构造函数- 、移动构造函数、复制赋值运算符或移动赋值运算符未删除
- 普通的未删除析构函数
这意味着该类没有虚函数或虚拟基类。
TriviallyCopyable 对象的标量类型和数组也是 TriviallyCopyable,以及此类类型的 const 限定(但不是可变限定(版本。
相关文章:
- C#中等价的C++内存复制
- 坚持将双指针管理的内存复制到二维数组
- OpenCL 将字符从全局内存复制到本地内存
- 内存C++复制是否将内存地址复制到另一个阵列
- 将内存复制到结构时,exc_bad_access
- 动态内存复制是如何工作的
- Cuda-从设备全局内存复制到纹理内存
- 使用动态内存复制类
- 将内存复制到标准::复制
- 通过指针的内存复制有时会丢失数据
- 内存访问与内存复制
- 使用汇编代码从内存复制到c++中的寄存器
- 执行 SSE 内存复制导致的堆损坏 - CRT 检查找不到任何内容
- 内存复制导致偏移量
- 如何将图像从全局内存复制到openCL的本地内存
- 从cuda 3D内存复制到线性内存:复制的数据不是我所期望的
- 使用内存复制对象时出现双自由或损坏错误
- c++内存复制结构体到字节数组中
- 使用内存复制对象数组
- 将原始数据从内存复制到文件(cuda)