使用memmove在C ++中的构造函数中初始化整个对象

时间:2016-09-24 14:33:48

标签: c++ memcpy memmove

使用memmove / memcpy用构造函数参数初始化对象是否安全? 似乎没有人使用这种方法但是当我尝试它时它工作正常 参数在堆栈中传递会导致问题吗?

说我有一个课程class foo { int x,y; float z; foo(); foo(int,int,float); }; 如下,

foo::foo(int x,int y,float z)
{
  memmove(this,&x, sizeof(foo));
}

我可以使用memmove初始化变量,如下所示吗?

{{1}}

4 个答案:

答案 0 :(得分:2)

这是未定义的行为。

显示的代码不会尝试初始化类变量。它尝试memmove()到类指针上,并假设类的大小为2*sizeof(int)+sizeof(float)。 C ++标准不保证。

此外,显示的代码还假设传递给构造函数的参数布局与此POD成员的布局布局相同。这也是C ++标准没有规定的。

使用memmove初始化单个类成员是安全的。例如,以下是安全的:

foo::foo(int x_,int y_,float z_)
{
   memmove(&x, &x_, sizeof(x));
   memmove(&y, &y_, sizeof(y));
   memmove(&z, &z_, sizeof(z));
}

当然,这没什么用处,但这是安全的。

答案 1 :(得分:1)

不,这不安全,因为基于标准,由于对齐/填充,成员不能保证立即紧接着。 更新后,这更糟糕,因为传递的参数及其顺序的位置不安全。

答案 2 :(得分:1)

  

我们应该忘记小的效率,大约97%的时间说:过早的优化是所有邪恶的根源。然而,我们不应该放弃那个关键的3%的机会。 - 唐纳德克努特

您不应该尝试优化您不确定需要的代码。在您能够执行此类优化之前,我建议您配置代码。通过这种方式,不会浪费时间提高某些代码的性能,这些代码不会影响应用程序的整体性能

通常,编译器足够智能,可以猜测您要对代码执行什么操作,并生成保持相同功能的高效代码。为此,您应该确保启用编译器优化(-Olevel标志或通过编译器命令参数切换单个标记)。

例如,我发现当编译器确定这样做很简单时(例如数据是连续的),有些编译器会将std::copy转换为memcpy。

答案 3 :(得分:0)

不,这不安全。这是未定义的行为。

代码

foo::foo(int x,int y,float z)
{
  memmove(this,&x, sizeof(foo));
}
与使用初始化列表

相比,

甚至不会保存任何输入

foo::foo(int x,int y,float z) : x(x), y(y), z(z)
{ }