memcpy与这个指针安全吗?

时间:2018-06-18 10:19:24

标签: c++ arrays memcpy this-pointer

我目前正在用C ++编写自己的字符串实现。 (仅供锻炼)。

但是,我目前有这个拷贝构造函数:

memcpy()

我希望稍微提高性能。因此,我使用obj提出了将*this复制到// "obj" has the same type of *this, it's just another string object string_base<T>(const string_base<T> &obj) { memcpy(this, &obj, sizeof(string_base<T>)); } 的想法。

就像那样:

*this

像这样覆盖web.xml的数据是否安全?或者这会产生任何问题吗?

提前致谢!

4 个答案:

答案 0 :(得分:3)

不,这不安全。来自cppreference.com:

  

如果对象不是TriviallyCopyable,则memcpy的行为未指定,可能未定义。

您的班级不是TriviallyCopyable,因为其复制构造函数是用户提供的。

此外,您的复制构造函数只会生成浅层副本(如果您需要,可能没问题,例如,应用了字符串的写时复制机制)。

答案 1 :(得分:2)

会产生问题。所有引用和指针都将被复制,甚至是指向raw_data的指针,它将与源对象相同。

作为使用memcpy的必备条件,您的课程应该:

  • Be Trivially Copyable
  • 没有引用或指针,除非:静态指针或不拥有指向的数据。除非您知道自己在做什么,例如实现写时复制机制,或者此行为是有意和管理的。

答案 2 :(得分:1)

正如其他人所说,为了使memcpy正常工作,被复制的对象必须是可以轻易复制的。对于模板中T这样的任意类型,您无法确定。当然,你可以检查它,但让其他人做检查要容易得多。不要编写那个循环并调整它,而是使用std::copy_n。如果适当的话,它将使用memcpy,而当它不是时,它将逐个元素地复制。所以改变

raw_data = new T[cap];
for (unsigned i = 0; i < cap; i++)
    raw_data[i] = obj.data()[i];

raw_data = new T[cap];
std::copy_n(obj.data(), cap, raw_data);

这也有一点点优点就是不会在循环的每次传递中评估obj.data(),这是编译器可能适用或不适用的优化。

答案 3 :(得分:0)

raw_data是成员的有限片段和指向new[]的{​​{1}}数组的指针看起来非常明显。如果你memcpy对象,你memcpy这个指针。你没有复制数组。

看看你的析构函数。它可能无条件地调用T。它不知道有多少副本存在。这意味着它经常调用delete[]。这是可以解决的:您需要类似delete[]的内容。这根本不是微不足道的;你必须担心该份额的线程安全性。显然,您不能只是shared_ptr该对象,因为这不会更新共享计数。