2016-08-12 10 views
-1

純粋な仮想関数で基本クラスBを継承したクラスAのオブジェクトに問題があり、私はptrオブジェクトのリストを持っています問題は、リスト内のオブジェクトから仮想メソッドにアクセスしようとすると、__vfptrテーブルが破損することがあることです。オブジェクトはリストにあり、削除されません。誰にもなぜこれが起こっているのかについての考えがありますか?問題は、アプリケーションの1つまたは2つのインスタンスを起動してもエラーは発生しないが、さらに多くのインスタンスを開始すると、アプリケーションの3番目または4番目のインスタンスで奇妙なアクセス違反が発生するということです。削除されていないオブジェクトで__vfptrテーブルが壊れています

少なくとも、vftableへのポインタがいつ変化しているかを追跡する方法はありますか?そのメソッドは複数の場所から呼び出され、おそらくこのエラーがランダムに発生することはもちろん、デバッガですべてを追跡することはできません。

はここにUPDATE 1つの

enter image description here

あなたにたくさんありがとう:あなたのコードではhttp://rextester.com/live/MRHR24728

//Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x86 

#include <iostream> 
#include <stdint.h> 

typedef struct 
{ 
    uint8_t name; 
}sName; 

class Base1 
{ 
public: 
    virtual ~Base1(){}; 

    virtual const sName* GetName() = 0; 
}; 

class Base2 : public Base1 
{ 
public: 
    Base2(){}; 
    virtual ~Base2(){} 

    virtual const sName* GetName() { return &_name; } 

private: 
    sName _name; 
}; 

class Base3 : public Base2 
{ 
public: 
    Base3(){} 
    virtual ~Base3(){} 
}; 

class Object : public Base3 
{ 
public: 
    Object(){} 
    ~Object(){} 
}; 

int main() 
{ 
    Object object; 
    Base1 *_logicalDevices[1] = {&object}; 

    const sName * test = _logicalDevices[0]->GetName(); // this is where it breaks sometimes when trying to access the GetName method 
    std::cout<<test->name; 
} 
+0

、コードや大型クラスの行数千の百がある – stryku

+0

いくつかのコードを投稿してください、私は、全体のことを合成しようとするでしょう@ stryku –

+0

updated @stryku –

答えて

2

Object objectをsnipetユーザーに提供デフォルトコンストラクタが呼び出され、default initializedです。あなたのBase2のデフォルトのフィールドには、_nameフィールドの初期化がないので、不確定な値に初期化されています。私はあなたのBase2コンストラクタを変更して、sName構造のためのコンストラクタを追加することをお勧め:

struct sName 
{ 
    uint8_t name; 
    sName() : name(0) {} 
}; 

class Base2 : public Base1 
{ 
    public: 
    Base2() 
     : _name() // <--- Default ctor of sName called 
    {}; 
    virtual ~Base2(){} 

    virtual const sName* GetName() { return &_name; } 

    private: 
    sName _name; 
}; 
+0

'不確定な値に初期化されました。彼らはその価値を決して読み取ることはなく、常に有効でなければならないメンバーのアドレスのみを読みます。初期化されていない_value_を読み込むまで、未定義の動作は含まれません。だから彼らは完全なコードを投稿していないし、クラッシュするプログラムは実際に返されたポインタを逆参照し、それが指している初期化されていない値を読み取り、それは問題の理由ではありません。 –

+0

...'std :: cout < name;' so +1 –

+0

のような不確定な値に初期化されていても、仮想メソッドを呼び出そうとするとエラーアクセス違反の読み込みが表示されます、アクセスできない_name –

関連する問題