C ++の多重継承とアップキャストされたスマートポインターの破壊により、VS2017でヒープが破損します

誰か

上記のコードでVSデバッガーの問題が発生しました:

class Animal {
public:


};


class Stupid {
public:

};


class Dog : public Stupid, public Animal {
public:


};

int main() {
    std::unique_ptr<Animal> animal = std::unique_ptr<Dog>(new Dog());
    animal.reset();
    return 0;
}

このコードは、「ntdl.dll」と「wntdll.pdb」を含む「animal.reset()」を実行した後にエラーをスローします。

「ignore」を複数回(3)回押した場合に、MSVCランタイムライブラリによってアサーションエラーが発生した式は次のとおりです。

1- _CrtIsValidHeapPointer(block)
2- is_block_type_valid(header->_block_use)
3- HEAP CORRUPTION DETECTED: before Free block (#-50331640) at 0x03737E21. CRT detected that the application wrote to memory before start of heap buffer.

しかし、Dogの継承順序を次のように変更すると、次のようになります。

class Dog : public Animal, public Stupid {
public:


};

コードは正常に実行されます。

このエラーはVisualStudio 2017でのみ発生し、Android StudioのIdeone試しましたが、継承の順序に関係なく正常に動作します。

ComicSansMS

渡したポインタがdeleteから戻ってきたものと同じではないため、これは壊れますnew

アップキャストとは、基本的に、派生へのポインタを取得し、それがベースへのポインタであると偽ることを意味します。単一継承の場合、これは正しく機能します。これは、ベース部分が常に派生オブジェクトに格納される最初のものであるためです。しかし、多重継承では、2つの基盤があります!

したがって、2塁にアップキャストするときは、実際にポインターの値変更して、ポインターが指しているものが実際にオブジェクトのそれぞれのベース部分になるようにする必要があります。デバッガーでポインターの値を調べることにより、次のことを確認できます。

Dog* d = new Dog;
Animal* a = d;

aポインタは、後ろに1つのバイトを指しますdポインタ。

すでに述べたように、これは、削除呼び出しで使用している基本クラスタイプに仮想デストラクタを追加することで修正できます(Animal例では)。これにより、コンパイラはポインタをに渡す前にポインタを正しく再調整するための追加のコードを生成しdeleteます。

gccは実際にここで空ベースクラスの最適化を実装しているため、この例はそこで機能することに注意してください。両方の拠点は同じオフセットに住んでいます。非静的データメンバーを基本クラスに追加し始めるとすぐに、そこで壊れ始めます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

ヒープの破損により、C ++でエラーが検出されました

分類Dev

ヒープの破損が検出されました| C

分類Dev

C-アレイを解放するときにヒープ破損が検出されました

分類Dev

テンプレートの使用によりC / C ++最適化コンパイラが破損しました

分類Dev

mysql CAPIプリペアドステートメントを使用したC ++でのスタック破損警告

分類Dev

mysql CAPIプリペアドステートメントを使用したC ++でのスタック破損警告

分類Dev

エラーc ++アサーションの失敗ヒープの破損が検出されました

分類Dev

クラス内のいくつかの配列でdelete []を呼び出しているときに「ヒープ破損が検出されました」-C ++

分類Dev

C ++:通常のブロック後にヒープの破損が検出されました

分類Dev

C ++:通常のブロック後にヒープの破損が検出されました

分類Dev

C ++ウィンドウがブレークポイントをトリガーしました-ヒープの破損

分類Dev

C ++のdeleteステートメントは、.net4.5プロセスでヒープ破損例外をスローします

分類Dev

C ++ヒープ破損、ただしユニットテストプロジェクトのみ

分類Dev

C#アプリでマーシャリングされた構造体を受け取った直後のヒープの破損

分類Dev

c ++前のステップで例外がスローされたときに、std :: shared_ptrによるポインター参照が破棄されるのはなぜですか

分類Dev

c ++ delete [] 2D配列によりヒープが破損しました

分類Dev

同じ派生クラスインスタンスへのポインタを仮想ベースポインタにアップキャストすると、常に同じアドレスが返されますか?C ++

分類Dev

C ++ポインター:配列のスタックが破損していました

分類Dev

C ++:このコードはコンパイルされますが、ランタイムチェックの失敗#2-をスローします-変数「num」の周りのスタックが破損していました。発生した

分類Dev

CとC ++の混合コードプログラミングで例外をキャッチした後、オブジェクトは破棄されません

分類Dev

ヒープが破損しています。C#dllimport、delphiPCharの戻り値

分類Dev

C ++でのテンプレート化された例外クラスの多重継承

分類Dev

「this」へのポインタをベースコンストラクタに渡すことにより、C ++ダイヤモンド継承を排除します

分類Dev

C ++:C ++は、コンテナー内のスマートポインターを破棄することをどのように知っていますか?

分類Dev

C ++での画像HTTPアップロードが破損しています

分類Dev

C#のwpfプロジェクトの「キャッチまたはスローされたタイプはsystem.exceptionから派生する必要があります」エラーを修正するにはどうすればよいですか?

分類Dev

<sizeof(T)>はc ++の継承されたクラステンプレートパラメータとして

分類Dev

C ++のコンストラクターで例外がスローされたときに、オブジェクトのメンバー変数を破棄する

分類Dev

Cのヒープが破損していて、理由がわかりません

Related 関連記事

  1. 1

    ヒープの破損により、C ++でエラーが検出されました

  2. 2

    ヒープの破損が検出されました| C

  3. 3

    C-アレイを解放するときにヒープ破損が検出されました

  4. 4

    テンプレートの使用によりC / C ++最適化コンパイラが破損しました

  5. 5

    mysql CAPIプリペアドステートメントを使用したC ++でのスタック破損警告

  6. 6

    mysql CAPIプリペアドステートメントを使用したC ++でのスタック破損警告

  7. 7

    エラーc ++アサーションの失敗ヒープの破損が検出されました

  8. 8

    クラス内のいくつかの配列でdelete []を呼び出しているときに「ヒープ破損が検出されました」-C ++

  9. 9

    C ++:通常のブロック後にヒープの破損が検出されました

  10. 10

    C ++:通常のブロック後にヒープの破損が検出されました

  11. 11

    C ++ウィンドウがブレークポイントをトリガーしました-ヒープの破損

  12. 12

    C ++のdeleteステートメントは、.net4.5プロセスでヒープ破損例外をスローします

  13. 13

    C ++ヒープ破損、ただしユニットテストプロジェクトのみ

  14. 14

    C#アプリでマーシャリングされた構造体を受け取った直後のヒープの破損

  15. 15

    c ++前のステップで例外がスローされたときに、std :: shared_ptrによるポインター参照が破棄されるのはなぜですか

  16. 16

    c ++ delete [] 2D配列によりヒープが破損しました

  17. 17

    同じ派生クラスインスタンスへのポインタを仮想ベースポインタにアップキャストすると、常に同じアドレスが返されますか?C ++

  18. 18

    C ++ポインター:配列のスタックが破損していました

  19. 19

    C ++:このコードはコンパイルされますが、ランタイムチェックの失敗#2-をスローします-変数「num」の周りのスタックが破損していました。発生した

  20. 20

    CとC ++の混合コードプログラミングで例外をキャッチした後、オブジェクトは破棄されません

  21. 21

    ヒープが破損しています。C#dllimport、delphiPCharの戻り値

  22. 22

    C ++でのテンプレート化された例外クラスの多重継承

  23. 23

    「this」へのポインタをベースコンストラクタに渡すことにより、C ++ダイヤモンド継承を排除します

  24. 24

    C ++:C ++は、コンテナー内のスマートポインターを破棄することをどのように知っていますか?

  25. 25

    C ++での画像HTTPアップロードが破損しています

  26. 26

    C#のwpfプロジェクトの「キャッチまたはスローされたタイプはsystem.exceptionから派生する必要があります」エラーを修正するにはどうすればよいですか?

  27. 27

    <sizeof(T)>はc ++の継承されたクラステンプレートパラメータとして

  28. 28

    C ++のコンストラクターで例外がスローされたときに、オブジェクトのメンバー変数を破棄する

  29. 29

    Cのヒープが破損していて、理由がわかりません

ホットタグ

アーカイブ