我可以删除使用memcpy()复制的类指针吗?

时间:2011-04-28 14:50:22

标签: c++ memcpy

以下代码段是否有效?

class Foo
{
public:
    int a;
    SomeClass* pb;

    Foo() {...}
    Foo(const Foo& rhs)
    {
         this->a = rhs.a;
         memcpy(this->pb, rhs.pb, sizeof(SomeClass));
    }
    ~Request()
    {
        delete this->pb; // Suppose pb is a result of copy constructor,
                         // Is this valid or is there a better way?
    }
};

6 个答案:

答案 0 :(得分:3)

您无法使用memcpy复制课程。 memcpy只是复制内存,而不是分配任何内容。

答案 1 :(得分:3)

您实际上没有为pb分配任何内容。如果您使用new进行分配,则在析构函数中使用delete完全有效。

但为什么你为什么要做memcpy?您应该使用类的复制构造函数,并让它以适当的方式复制自身。当类是POD类型的简单结构时,memcpy可以远程接受的时间。

答案 2 :(得分:1)

它是有效的,因为它会编译。但它有错误。你从未分配任何内存,所以你需要先做。但绝对没有理由使用memcpy,在大多数情况下,它做错了。就这样做:

Foo(const Foo& rhs)
    :a(rhs.a),
     pb(new SomeClass(*rhs.pb))
{    
}

或者更好的是,使用智能指针,您不必担心删除。或者更好的是,如果您保留对象的唯一所有权,请不要使用指针。

答案 3 :(得分:1)

此代码段错误,因为如果不调用delete来分配内存,则无法调用new

在大多数情况下,您的memcpy调用也会导致分段错误,因为您正在复制到未初始化的指针。在调用SomeClass之前,您应该为memcpy指针分配memort。

答案 4 :(得分:1)

将memcpy与POD结构/对象以外的任何东西一起使用(“普通旧数据” - 没有非默认构造函数或析构函数的东西,以及虚拟方法)是灾难的一个方法。如果您修复程序以便使用memcpy复制包含指向类项的“普通”指针的POD结构,则作为该结构的一部分复制的任何指针必须与通过其他方式复制的指针相同。必须“删除”任何此类指针的一个副本(或原始) - 不多也不少。如果您复制指针并放弃原始而不调用“删除”,则应在一个副本上调用“删除”。

一般来说,应该避免在C ++中使用memcpy;在C语言中,结构永远不会有任何“隐藏”信息,这些信息可能会被memcpy留在不一致的状态,但在C ++中它们经常会这样做(除了POD结构)。虽然C ++的设计主要与C兼容,但事实上C中的某些东西是合法的并不意味着它在C ++中是正确的。

答案 5 :(得分:0)

您没有使用new为该指针分配内存,所以绝对不应该在其上使用deletememcpy没有为您分配任何内存。

具体来说,您应该调用delete的唯一指针是先前由new返回的指针,或者是空指针。根据C ++ 03标准3.7.3.2/3-4,在任何其他指针上使用delete是未定义的行为。

  

第一个参数的值   提供给其中一个解除分配   标准中提供的功能   库可以是空指针值;   如果是这样,调用deallocation   功能无效。 否则,   提供给运营商的价值   删除标准库中的(void *)   应该是返回的值之一   之前的任何一个调用   operator new(size_t)或运算符   new(size_t,const std :: nothrow_t&)

     

... [剪断] ...

     

使用无效指针的效果   价值(包括将其传递给   解除分配功能)是   未定义。)