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

Can I delete class pointer copied using memcpy()?

本文关键字:复制 指针 删除 memcpy      更新时间:2023-10-16

下面的代码片段有效吗?

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?
    }
};

您实际上没有为pb分配任何内容。如果用new分配它,那么在析构函数中使用delete是完全有效的。

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

不能使用memcpy复制类。memcpy只是复制内存,不分配任何东西

它是有效的,因为它会编译。但它也有很多错误。您从未分配过任何内存,因此需要先分配内存。但是绝对没有理由使用memcpy,而且在大多数情况下,它会做错误的事情。只需这样做:

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

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

这个代码片段是错误的,因为如果不调用new来分配内存,就不能调用delete

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

将memcpy用于POD结构/对象("普通旧数据"——没有非默认构造函数或析构函数的东西,以及带有虚拟方法)以外的任何东西都是一种灾难。如果你修改你的程序,使你使用memcpy来复制一个POD结构,其中包含一个指向类项的"普通"指针,那么作为该结构的一部分复制的任何指针都必须像通过其他方式复制的指针一样处理。必须"删除"任何此类指针的一个副本(或原始)——不多也不少。如果您复制指针并放弃原始指针而没有对其调用"delete",那么您应该只对一个副本调用"delete"。

一般来说,应该避免在c++中使用memcpy;在C语言中,结构从来没有任何"隐藏"信息,这些信息可能会被memcpy保留在不一致的状态,但在c++中,它们经常会这样做(POD结构除外)。尽管c++的设计主要是为了与C兼容,但在C中合法的事情并不意味着在c++中是正确的。

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

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

第一个参数的值提供给其中一个解分配标准中提供的功能库可以是空指针值;如果是,则调用重新分配功能没有作用。否则,提供给运算符的值在标准库中删除(void*)返回的值之一一个先前的调用operator new(size_t)或operatorNew (size_t, const std::nothrow_t&)

(剪)…

使用无效指针的效果值(包括将其传递给释放函数)为定义。)