标准定义我们可以通过以下方式使用std :: memcpy:
对于任何简单的可复制类型T,如果指向T的两个指针指向 不同的T对象obj1和obj2,其中obj1和obj2都不是 基类子对象,如果构成obj1的基础字节(1.7)是 复制到obj2中,obj2随后应保持与obj1相同的值。
如果我们将该函数应用于非平凡可复制类型的对象,我们可能会遇到什么问题?以下代码的工作原理就好像它适用于普通可复制类型:
#include <iostream>
#include <cstring>
using std::cout;
using std::endl;
struct X
{
int a = 6;
X(){ }
X(const X&)
{
cout << "X()" << endl;
}
};
X a;
X b;
int main()
{
a.a = 10;
std::memcpy(&b, &a, sizeof(X));
cout << b.a << endl; //10
}
答案 0 :(得分:5)
你问:
如果我们将该函数应用于非平凡可复制类型的对象,我们可能会遇到什么问题?
这是一个非常简单的示例,说明了将std::memcpy
用于非平凡可复制类型的对象的问题。
#include <cstring>
struct A
{
A(int size) : size_(size), data_(new int[size]) {}
~A() { delete [] data_; }
// The copy constructor and the copy assignment operator need
// to be implemented for the class too. They have been omitted
// to keep the code here minimal.
int size_;
int* data_;
};
int main()
{
A a1(10);
A a2(20);
std::memcpy(&a1, &a2, sizeof(A));
// When we return from the function, the original data_ of a1
// is a memory leak. The data_ of a2 is deleted twice.
return 0;
}
答案 1 :(得分:1)
考虑这个程序:
#include <memory>
int main() {
std::shared_pointer<int> x(new int);
{
std::shared_pointer<int> y;
memcpy((void*)&y, (void*)&x, sizeof(x));
}
*x = 5;
}
由于我们使用x
而不是赋值运算符将y
复制到memcpy
,因此引用计数未更新。因此,在该块的末尾,调用y
的析构函数。它发现它的引用计数为1,这意味着它是唯一指向堆分配整数的shared_pointer实例。所以删除它。
main
的最后一行可能会出现段错误,因为x
指向已删除的对象。