Frage

Wie Sie im Code unten sehen können, ich habe eine abstrakte Basisklasse „HostWindow“ und Klasse, die leitet daraus ab, „Chrome“. Alle Funktionen sind in Chrome implementiert. Das Problem ist, kann ich nicht nennen Funktionen in Chrome, wenn sie sind virtuell.

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;
}

kann also sagen, dass wir eine Instanz von Chrome haben, und wir nennen einige Funktionen:

WebCore::Chrome *chrome = new Chrome();
chrome->repaint(IntRect(), true); // Null pointer error
chrome->focus(); // returns void (works)

Der Nullzeiger-Fehler erhalte ich, wenn ich virtuelle Funktionen aufrufen lautet:

  

Programm empfangene Signal EXC_BAD_ACCESS, kann nicht Zugriffsspeicher.   Grund: KERN_PROTECTION_FAILURE unter der Adresse: 0x00000008

Jede Idee, was passiert?

Update: Wie viele von Ihnen darauf hingewiesen - dieser Code tatsächlich ausgeführt wird. Leider kann ich nicht mehr voll Beispiel liefern, da der Code tief in WebCore (WebKit) ist. Allerdings habe ich das Problem eingegrenzt. Wenn ich eine Chrome-Instanz manuell erstellen Aufruf virtueller Funktionen zu arbeiten. Also das Problem mit dieser speziellen Chrom-Instanz ist - es kann nicht richtig instanziiert. Nun wird die Chrome-Instanz in einem Konstruktor einer anderen Klasse instanziiert. Ich werde weiter untersuchen ...

Update 2: Ok, die Prüfung des Vtable auf die säumige Beispiel zeigt, dass es die null; von GDB:

p *(void **)chrome
$52 = (void *) 0x0

Eine normale Instanz hat eine korrekte V-Tabelle. Also, ich habe herauszufinden, warum die VTable ist gleich Null - Ich frage mich, wie das passieren konnte? Vielleicht, weil es in einigen anderen Klassen instanziiert Sein Constructor?

Update 3: Sieht aus wie ich bin richtig über das Thema es die Instanziierung innerhalb einer anderen Klasse Konstruktor zu sein.

Also, bevor die Instanziierung sah wie folgt aus:

Page::Page(ChromeClient* chromeClient, ...)
    : m_chrome(new Chrome(this, chromeClient))

Und m_chrome ist eine ungültige Instanz, mit einem Null-VTable. Ich habe die Instanziierung geändert, so dass es passiert, wenn das erste Mal die Variable benötigt wird (dies beinhaltet ChromeClient für später speichern):

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;
}

Nun ist die Seite :: Chrom () Beispiel ist die richtige, mit der richtigen VTable - ziemlich seltsam

Update 4: Letztes Update, das verspreche ich :). Ok, so habe ich es genau geortet nach unten. Sie erhalten die richtige Instanz, mit der V-Tabelle, wenn Sie es in Seite Konstruktor Körper instanziiert. Wenn Sie es in Seite Konstruktor Kopf instanziiert, hat es keinen VTable. Gibt es eine Beschränkung in der Art der variablen Einstellung, die Sie in einem Konstruktor Kopf tun können? Ich denke, das ist eine andere Frage Stackoverflow.

Danke Jungs für so hilfreich zu sein.

War es hilfreich?

Lösung

Ja, die 'this' Zeiger Null ist. In 8 erhalten einen Offset, und es ist deine Schuld. Sie haben offenbar kein eigentliches Objekt überhaupt.

Da Sie nicht genug Code geschrieben haben wirklich in den Griff zu kommen, ich bin zu raten. Entweder ist die ganze ist dieser Zeiger 0, oder die virtuellen Funktionstabellenzeiger 0, vielleicht, weil das Objekt gelöscht wurde, nachdem es erstellt wurde und bevor Sie versuchen, es zu nennen.

Der beste Rat, den ich Ihnen geben kann, ist eine viel kleinere Retorten zu erstellen. Entweder Sie Ihr Problem finden, oder Sie werden mit einem bebuchbare Beispiel am Ende.

Die vtbl ist nicht an Ort und Stelle in einem Fall bis zum Ende des Bauprozesses. In der Tat erfordert die Spezifikation progressive Veränderung der vtbl Bauzustand der Klassenhierarchie entsprechen.

Andere Tipps

Können Sie den vollständigen Code posten?

Nach geringfügiger Änderung im Code (was auch immer verfügbar ist), funktioniert es:

#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;
}

Ich bin mit der Code-Basis nicht vertraut Sie haben, sollte aber nicht schreiben Sie die folgende:

// note the 'WebCore::Chrome()'
WebCore::Chrome *chrome = new WebCore::Chrome();
chrome->repaint(IntRect(), true); // 'chrome' should be a valid pointer now

statt:

WebCore::Chrome *chrome = new Chrome();
chrome->repaint(IntRect(), true); // Null pointer error

ssume Ihre nicht kopierbar sind wie folgt (zumindest für mein tat)

class NonCopyable
{
protected:
    NonCopyable() {}
    ~NonCopyable() {}
private:
    NonCopyable( const NonCopyable& );
    const NonCopyable& operator=( const NonCopyable& );
};

nach dem Einfügen öffentlich Modifikator Klasse Chrom Funktion und einige Dummy-Implementierung für sie, das Ganze funktionierte ohne erklärtes Problem.

  
    
      

Es gibt kein Problem mit dem Code geschrieben, es könnte sein, Sie Dinge falsch machen und nicht diejenigen Teil hier veröffentlichen.

    
  

Schließlich machen gerade für Zuordnungsfehler zu überprüfen. (Ja, "neu" sind Zuteilung auf Heap)

Ich fand, dass dies verursacht wurde, so dass alle Symbole exportiert werden.

Normalerweise WebCore hat nur eine Teilmenge von Symbolen exportiert -. Grundsätzlich auf Dinge, die WebKit Bedürfnisse

ich geändert, dass jedes Symbol zu exportieren -. Und es irgendwie diesen Fehler verursacht

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top