Gal*_*age 3 c++ arrays object memcpy
最近我在我的项目中遇到了错误双重免费或损坏错误.在一些测试运行之后,问题被固定到使用memcpy的复制功能.
class Pen
{ string make;
string model;
string color;
public:
Pen();
}
class A
{ private:
Pen* array; //an array that stores pen objects
int NumOfItem;
int Maxsize;
void CopyArray(const A& source);
public:
A();
A(const A& source);//copy constructor where uses the CopyArray private mentioned below
~A();
}
void A::CopyArray(const A& source)
{
memcpy(array, source.array, len * sizeof(Pen));//
return;
}
void A::A(const A& source)//copy constructor that performs a deep copy from B
{ array = new Pen[source.NumOfItem];
NumOfItem = source.NumOfItem;
MaxisIze=source.Maxize;
CopyArray(source);
}
Run Code Online (Sandbox Code Playgroud)
当我更改我的代码并使用for循环复制每个参数时,它可以工作.我仍然试图理解为什么memcpy导致问题,如果只是将所有数据按位复制到新对象......(对于凌乱的格式抱歉...)
das*_*ght 10
使用的问题memcpy是它绕过了复制构造函数.只有当您的类由基元组成时,才可以.
但是,Pen类具有类型的非原始数据成员std::string.这些对象需要复制复制构造函数的调用.memcpy不会对复制构造函数执行任何调用,这会导致内部表示std::string变为共享,从而导致销毁时出现未定义的行为.
另一方面,使用循环复制会调用复制构造函数,因此代码运行时没有问题.
C++标准库提供了一个用于复制调用范围的实用程序函数std::copy.使用此函数可以避免您看到的问题,因为它会根据需要调用复制构造函数.
您只能用于memcpy()复制易于复制的对象.让我们看看是否Pen符合这一要求.
#include <string>
using namespace std;
class Pen {
string make;
string model;
string color;
public:
Pen();
};
static_assert(std::is_trivially_copyable<Pen>::value, "Pen is not trivially copyable");
Run Code Online (Sandbox Code Playgroud)
编译时,这将返回错误:
blah.cc:12:1: error: static_assert failed "Pen is not trivially copyable"
static_assert(std::is_trivially_copyable<Pen>::value, "Pen is not trivially copyable");
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
所以,我们可以清楚地看到,这Pen不是简单的可复制,所以我们不能使用memcpy()它.你可能应该使用std::copy.