我可以删除使用 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?
}
};
Is the following snippet of code valid?
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?
}
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您实际上尚未为
pb
分配任何内容。如果您使用new
分配它,那么在析构函数中使用delete
是完全有效的。但是为什么哦为什么你要做一个
memcpy
?您应该使用类的复制构造函数并让它以适当的方式复制自身。 唯一 memcpy 远程可接受的情况是该类是 POD 类型的简单结构时。You haven't actually allocated anything for
pb
. If you allocate it withnew
, then usingdelete
in the destructor is perfectly valid.But why oh why are you doing a
memcpy
? You should be using the copy constructor of the class and letting it copy itself in the appropriate fashion. The only time a memcpy would be remotely acceptable is when the class is a simple struct of POD types.您无法使用
memcpy
复制类。而memcpy只是复制内存,而不是分配任何东西。You can't copy classes using
memcpy
. Andmemcpy
is just copying memory, not allocating anything.它是有效的,因为它会编译。但它却充满了错误。您从未分配过任何内存,因此您需要首先执行此操作。但绝对没有理由使用 memcpy,而且在大多数情况下,它会做错误的事情。只需这样做:
或者更好的是,使用智能指针,您不必担心删除。或者更好的是,如果您保留该对象的唯一所有权,则根本不要使用指针。
It's valid, as in it will compile. But it is stricken with errors. You never allocated any memory, so you'd need to do that first. But there is absolutely no reason to use memcpy, and in most cases, it does the wrong thing. Just do this:
Or better yet, use a smart pointer, and you don't have to worry about deleting. Or better yet, don't use a pointer at all if you retain sole ownership of the object.
此代码片段是错误的,因为如果不调用
new
来分配内存,则无法调用delete
。此外,在大多数情况下,您的 memcpy 调用可能会导致分段错误,因为您正在复制到未初始化的指针。在调用
memcpy
之前,您应该为SomeClass
指针分配内存。This code snippet is wrong because you can't call
delete
without calling tonew
for allocation of memory.Also your
memcpy
call can cause segmentation fault in most cases, because you are copying to unintialized pointer. You should allocate memort forSomeClass
pointer before calling tomemcpy
.将 memcpy 与 POD 结构/对象(“普通旧数据”——没有非默认构造函数或析构函数以及虚拟方法的东西)以外的任何东西一起使用都是灾难的根源。如果您修复程序,以便使用 memcpy 复制包含指向类项的“普通”指针的 POD 结构,则作为该结构的一部分复制的任何指针都必须与通过其他方式复制的指针进行相同的处理。必须“删除”任何此类指针的一份副本(或原始副本)——不多也不少。如果您复制指针并放弃原始指针,而没有对其调用“delete”,则应该对一个副本调用“delete”。
一般来说,应该避免在 C++ 中使用 memcpy;在 C 中,结构从来没有任何“隐藏”信息,这些信息可能会被 memcpy 留在不一致的状态,但在 C++ 中它们经常这样做(POD 结构除外)。尽管 C++ 被设计为与 C 大部分兼容,但某些东西在 C 中合法并不意味着它在 C++ 中是正确的。
Using memcpy with anything other than POD structures/objects ("plain old data"--things with no non-default constructors or destructors, and with virtual methods) is a recipe for disaster. If you fix your program so that you're using memcpy to copy a POD structure which contains an "ordinary" pointer to a class item, any pointers copied as part of that structure must be handled the same as pointers copied via other means. Exactly one copy (or the original) of any such pointer must be "deleted"--no more and no less. If you copy the pointer and abandon the original without calling "delete" on it, you should then call "delete" on exactly one copy.
In general, one should avoid using memcpy in C++; in C, structures never had any "hidden" information which could be left in an inconsistent state by memcpy, but in C++ they often do (with the exception of POD structures). Although C++ is designed to be mostly compatible with C, the fact that something is legal in C does not mean that it is proper in C++.
您尚未使用
new
为该指针分配内存,因此绝对不应该对其使用delete
。memcpy
没有为您分配任何内存。具体来说,您应该调用
delete
的唯一指针是先前由new
返回的指针或空指针。根据 C++03 标准 3.7.3.2/3-4,对任何其他指针使用delete
都是未定义的行为。You haven't allocated memory for that pointer using
new
, so you absolutely shouldn't be usingdelete
on it.memcpy
isn't allocating any memory for you.Specifically, the only pointers you should be invoking
delete
on are pointers that have previously been returned bynew
, or a null pointer. To usedelete
on any other pointer is undefined behaviour, according to the C++03 standard, 3.7.3.2/3-4.