-2

どのような状況で、クラスのオブジェクトがオブジェクトへの挿入を保証しinvisible dataますか?

memcpyの代わりにオブジェクトのコピーを使用copy-assignmentする場合、コンパイラが不可視のデータをオブジェクトに挿入することがあります。そのためmemcpy、オブジェクトのメモリ レイアウトがクラッシュした可能性があります。

仮想機能が含まれている場合、POD ではありません。ただし、仮想が含まれているため、関数がクラッシュしない可能性があり、定義されていません。memcpy が確実に間違っている例を教えてください。

一部の人々は影響をshared_ptr与えると言いましたmemcpy、私は試しましたが、クラッシュしません

誰かがそれを証明するためにテストデモを書くことができますか?

4

1 に答える 1

3

shared_ptrは良い例です。オブジェクト表現をコピーすると、同じオブジェクトへの 2 番目のポインターが得られますが、使用回数は増加しません。使用回数がポインターの数と等しくなければならないという不変条件を破ると、ダングリング ポインターの逆参照や同じオブジェクトの 2 回の削除など、未定義の動作が発生する可能性があります。

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`
于 2013-02-21T10:45:49.080 に答える