2013-02-21 128 views
-2

在什么情况下,Class的对象将保证将invisible data插入到对象中?memcpy not-POD objects导致未定义的行为

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

如果它包含virutal功能,那么它不是POD。 但包含虚拟,该功能可能不会崩溃,它没有被定义。 有人可以给我任何memcpy肯定是错误的例子。

有人说,shared_ptr影响memcpy,我试过了,但它不会崩溃

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

+1

memcpy non-POD是未定义的行为。这是一个肯定的声明(这是真的)。什么是问题? – 2013-02-21 10:16:45

+2

'memcpy'' shared_ptr'几乎可以保证访问释放的内存,并且可能还会进行双重删除。仅仅因为一个简单的例子不会崩溃并不意味着它可以工作。 – 2013-02-21 10:34:43

+0

我认为不会崩溃比在这种情况下崩溃更糟糕。在一个更复杂的系统中,你将会处理垃圾数据,这将是一个令人困惑的头痛。 – kylefinn 2017-08-17 00:00:47

回答

3

shared_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. 

你还别说虚函数。如果您复制派生类的基础子对象,这些可能会导致问题;产生的对象将(可能)指向虚拟表的错误类:

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` 
相关问题