C++ memcpy非POD对象导致未定义的行为

C++ memcpy非POD对象导致未定义的行为,c++,memcpy,C++,Memcpy,在什么情况下,类的对象将保证向对象中插入不可见数据 人们通常说,当使用复制对象的memcpy而不是copy assignment时是不行的,有时编译器会将不可见的数据插入到对象中。因此,在memcpy之后,对象内存布局可能会崩溃 如果它包含virutal函数,那么它不是POD。 但包含虚拟,函数可能不会崩溃,它未定义。 谁能给我举个例子,说明memcpy肯定是错的 有人说我试过了,但是没有崩溃 有人可以编写一个测试演示来证明这一点吗?shared\u ptr就是一个很好的例子:复制对象表示将为您

在什么情况下,类的对象将保证向对象中插入
不可见数据

人们通常说,当使用复制对象的
memcpy
而不是
copy assignment
时是不行的,有时编译器会将不可见的数据插入到对象中。因此,在
memcpy
之后,对象内存布局可能会崩溃

如果它包含virutal函数,那么它不是POD。 但包含虚拟,函数可能不会崩溃,它未定义。 谁能给我举个例子,说明memcpy肯定是错的

有人说我试过了,但是没有崩溃


有人可以编写一个测试演示来证明这一点吗?

shared\u ptr
就是一个很好的例子:复制对象表示将为您提供指向同一对象的第二个指针,但不会增加使用计数。一旦您打破了使用计数必须等于指针数量的不变量,您将面临未定义的行为,例如取消对悬挂指针的引用,并删除同一对象两次:

shared_ptr<int> good(new int(42));
shared_ptr<int> evil;

memcpy(&evil, &good, sizeof evil); // Breaking invariant
good.reset();                      // Deletes object

*evil = 666;                       // BOOM! accesses deleted object
evil.reset();                      // BOOM! deletes object a second time.

memcpy非POD是未定义的行为。这是一个肯定的说法(这是真的)。问题是什么?
memcpy
ing a
shared\u ptr
几乎可以保证访问释放的内存,并且可能会进行双重删除。仅仅因为一个简单的例子不崩溃并不意味着它有效。我认为在这种情况下,不崩溃比崩溃更糟糕。在更复杂的系统中,您将处理垃圾数据,这将是一个令人困惑的难题。
struct Base {
    virtual int f() {return 0;}
};

struct Derived : Base {
    int x;
    virtual int f() {return x;}
};

Base * good = new Derived;
Base evil;

memcpy(*evil, good, sizeof evil); // Base object with Derived vtable (probably)

evil->f(); // BOOM! probably accesses nonexistent member `x`