継承されたクラスの"無効なポインタがエラー"を呼び出す時に仮想機能
-
20-09-2019 - |
質問
ご覧のとおりに以下のコードは、抽象基底クラス"HostWindow"は、クラスに由来することになる"クロム".すべての機能を実施したロードしてくださいの発行はできません電話機能クロームだけでなく、virtualなのです。
class HostWindow : public Noncopyable {
public:
virtual ~HostWindow() { }
// Pure virtual functions:
virtual void repaint(const IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false) = 0;
virtual void scrollbarsModeDidChange() const = 0;
}
class Chrome : public HostWindow {
// HostWindow functions:
virtual void repaint(const IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false);
virtual void scrollbarsModeDidChange() const;
void focus() const;
}
では、いいインスタンスのクロム、我々は少数の機能:
WebCore::Chrome *chrome = new Chrome();
chrome->repaint(IntRect(), true); // Null pointer error
chrome->focus(); // returns void (works)
場合は、nullポインタがエラーを取得しまま通話で仮想機能には:
プログラム受信信号EXC_BAD_ACCESSなアクセス。理由:KERN_PROTECTION_FAILUREでアドレス:0x00000008
う何が起こっているか?
更新: 多くのご指摘-このコードを実際に運行しています。残念ながらいを提供しようではありませんの例では、コードの奥深くWebCore(WebKit).しかし、縮小している問題です。場を創り出していクロームインスタンスを手動で呼び出し、仮想機能です。それでは何が問題かというとこの特定のクロームインスタンスでないインスタンスが生成されます。現在、クロームインスタンスのインスタンスが生成されるコンストラクタのクラスです。私が調査さら---
更新2: Okを調べるvtableの違反したインスタンスを示すことがnull;からGDB:
p *(void **)chrome
$52 = (void *) 0x0
通常のインスタンスが正しいvtable.なので、もちろん、今年も行にvtableはnil-どのように思われるでしょうかが起こるのか。しかも、インスタンスを生成の一部に他のクラスのコンストラクタ?
更新3: いと思ってしまう正しいこの問題に関してこのインスタンス化中に別のストックのコンストラクタです。
なので、前のインスタンス化を見ようになります:
Page::Page(ChromeClient* chromeClient, ...)
: m_chrome(new Chrome(this, chromeClient))
とm_chromeは無効なインスタンスは、nil vtable.私のインスタンス化で起こる初めての変数に対応するためには、この節ChromeClient後):
Page::Page(ChromeClient* chromeClient, ...)
: m_chrome(0)
, m_chrome_client(chromeClient)
Chrome* Page::chrome() const {
if(!m_chrome) {
m_chrome = new Chrome(this, m_chrome_client);
}
return m_chrome;
}
現在のページをご覧ください::クローム()のインスタンスは、正しい、適切にvtable-よ!
更新4: 最終更新をお約束します:).Okなんでゆくでしょう。く、正しいインスタンスのvtableた場合、インスタンスを生成するページのコンストラクタます。場合はインスタンスを生成するページのコンストラクタの本ではあまりないのvtable.制限はありまでの種類可変設定できないコンストラクタのワールドパネル社です。いのではないでしょうかは別Stackoverflowます。
おかげっています。
解決
あり、このポインタがゼロになります。追加-8からのオフセットあり。だそうでない実際のオブジェクトです。
まだ投稿は十分のコードに政策研究大学院大学、私の推測.のいずれかの全体のこのポインタが0、または、仮想関数テーブルのポインタは0になられているためか、このオブジェクトが削除された後で作成され、前だけます。
の助言を日本語訳を見てもわかりませんで作りはるかに小さな試験です。どちらかだけの問題やまとpostable例です。
のvtblなんてできない場所にインスタンスで建設す。この仕様を必要と累進変更にvtbl合わせの状態のクラス上位の階層となります。
他のヒント
きの完了コードについて教えてください。
後に若干の修正コード(うご)を動作させることができ:
#include <iostream>
class HostWindow {
public:
virtual ~HostWindow() { }
// Pure virtual functions:
virtual void repaint(const int , bool contentChanged, bool immediate = false, bool repaintContentOnly = false) = 0;
virtual void scrollbarsModeDidChange() const = 0;
};
class Chrome : public HostWindow {
public:
// HostWindow functions:
virtual void repaint(const int , bool contentChanged, bool immediate = false, bool repaintContentOnly = false)
{
std::cout << "In repaint." << std::endl;
}
virtual void scrollbarsModeDidChange() const { }
void focus() const
{
std::cout << "In focus." << std::endl;
}
};
int main()
{
Chrome *chrome = new Chrome();
chrome->repaint(1, true); // Null pointer error
chrome->focus();
delete chrome;
return 0;
}
私は知らないのコードベースでもない、次のように書き換え:
// note the 'WebCore::Chrome()'
WebCore::Chrome *chrome = new WebCore::Chrome();
chrome->repaint(IntRect(), true); // 'chrome' should be a valid pointer now
代わりに:
WebCore::Chrome *chrome = new Chrome();
chrome->repaint(IntRect(), true); // Null pointer error
ssume非copyableとして以下の(少なくとも地雷かった)
class NonCopyable
{
protected:
NonCopyable() {}
~NonCopyable() {}
private:
NonCopyable( const NonCopyable& );
const NonCopyable& operator=( const NonCopyable& );
};
挿入後、 公開 修飾クラスクロムの機能、一部のダミーを実施し、全体にもたく述べての問題です。
ありませんの問題、コードを掲載していますタンダードというわけでは間違いない投稿者の一環です。
最後に、確認のための配置ます。("yes"、"新しい"の配分にヒープ)
そのことによって生じる可能象徴されます。
通常、WebCoreのみサブセットの記号に輸出-基本的にはいるWebKitます。
いる輸出べてのシンボルでなんとかこのエラーになります。