2016-10-14 5 views
2

Visual Studio 2015では、foo()の終了時に次のエラーメッセージが表示されます。HEAP [NameOfExecutable.exe]:RtlValidateHeap(00520000)に無効なアドレスが指定されています、005332D4)Visual Studio:サブクラスの一意のポインタのベクトルがクラッシュする

注:

  • 私はBから "仮想" キーワードを削除::ボブ()、プログラムは完全に正常に動作します。 "G ++ -std = C++ 11" でコンパイルされたとき

  • プログラムは、コマンドライン(のVisual Studioの外部)から正常に動作します。

  • push_back()内でstd :: move()を使用しても出力は変更されませんでした。

#include <vector> #include <memory> #include <iostream> class A { int a; }; class B : public A { int b; virtual void bob() { }; }; void foo() { std::vector<std::unique_ptr<A>> test; test.push_back(std::unique_ptr<B>(new B)); } int main() { foo(); std::cout << "Reached the end\n"; std::cin.get(); }

私が間違って何をしているのですか?助けてくれてありがとう!

答えて

0

コードをデバッグすると、testのデストラクタが呼び出されたときに、終了点foo()で例外が発生することがわかります。

std::vectorstd::unique_ptrの両方が自分のメモリを管理しているので、今度は割り当てられたオブジェクトBが破棄されます。

ここでの問題点は、Aポインタで格納することです。そのため、Aクラスのデストラクタが呼び出されます。単に「A」へのパブリック仮想デストラクタ紹介し、その問題を解決するには

:このデストラクタは仮想作り、ちょうど私が理解しておいてくださいする

class A 
{ 
    int a; 
public: 
    virtual ~A() {} 
}; 
+0

は正しい、Bのデフォルトのデストラクタを呼び出すことができますか? –

+0

@AaronK確かに、それは普通の 'virtual'メソッドと同じです。もしそれが基本クラスの' virtual'ならば、それは自動的に子孫の 'virtual'です。もちろん、あなたは常に明示的に私はおそらくまた 'A'と 'B'のデストラクタの両方ができ、全体の問題は何かが欠けA'デストラクタ'に関するものではありませんことを追加する必要があり、単にコード – Ap31

+0

を明確にするために、あまりにもvirtual' 'としてBのデストラクタを指定することができます空のボディを持っていれば、 'virtual'デストラクタを持たないベースポインタの' delete'はUBです。 – Ap31

関連する問題