Zeiger nach Konstruktoraufruf auf NULL



  • Hi Leuts,

    der Titel ist evtl. etwas ungluecklich gewaehlt, wollte allerdings nicht einen
    zu langen Titel schreiben. Jetzt zu meinem Problem oder besser zu einem
    Phaenomen, welches ich nicht verstehe:

    Auf der Arbeit haben wir eine Klasse, die nennt sich 'HilfeDB'. Sie enthaelt
    eine Puffervariable vom Typ 'HilfeTyp *'. Nun ruft diese den Konstruktur
    ihrer Basisklasse auf (DataBaseVL), welche ihrerseits den Konstruktor ihrer
    Basisklasse aufruft (DataBase). Das sieht ungefaehr so aus:

    HilfeDB::HilfeDB(int defsize)
      : DataBaseVL(DBBTrieve, FN_HILFE, (void **)&m_buf, defsize)
    {
    }
    

    Innerhalb der DataBaseVL wird irgendwo Speicher reserviert und 'm_buf' auf
    diesen Umgebogen. Im Debugger zeigt 'm_buf' auf die Korrekte Adresse, auch
    noch, wenn ich an das Ende des 'HilfeDB'-Konstruktors komme. Doch danach
    ist 'm_buf' auf NULL gesetzt.

    Irgendwo im Quelltext:

    HilfeDB  *hdb;
    //und weitere deklarationen
    try
    {
       hdb = new HilfeDB;
    }//<---hier ist hdb::m_buf jetzt NULL
    //...
    

    Ich frage mich, wie das sein kann?

    Irgendwelche Ideen? Danke im Voraus!

    mfg
    v R



  • Hallo,
    wenn ich das richtig sehe, dann intialisierst du eine Member-Variable HilfeDB in einer Basisklasse.

    Nun scheint es so, dass dein Compiler im Debug-Modus alle Member im Konstruktor, wenn nicht anders angegeben, mit Default-Werten initialisiert.

    Das heißt erst wird m_buf in einem Basisklassen-Ctor gesetzt und dann, wenn schließlich der Konstruktor von HilfeDB läuft, wird m_buf mit 0 initlaisiert.

    Das Problem ist, dass du m_buf veränderst, bevor es überhaupt existiert.
    Ich würde also vorschlagen m_buf erst im Ctor von HilfeDB zu initialisieren.



  • HumeSikkins schrieb:

    ...
    Das Problem ist, dass du m_buf veränderst, bevor es überhaupt existiert.
    ...

    Hi,

    erstmal danke fuer die Antwort, klingt irgendwie auch logisch, aber:

    Ich schreibe doch beispielsweise auch sowas um Member zu initialisieren:

    MyClass::MyClass(int param)
     : m_param(param)
    {}
    

    Hier existiert doch 'm_param' auch schon, oder verwechsel ich hier irgendwas?

    Der Code um den es geht ist von meiner Arbeit und leider kann ich 'm_buf'
    nicht so ohne weiteres (zumindest weiss ich noch nicht wie) in HilfeDB
    setzen, denn innerhalb von DataBaseVL wird eine Membervariable instanziiert,
    der 'm_buf' uebergeben wird und innerhalb dessen Konstruktors wird
    'm_buf' auf die entsprechende Adresse umgebogen.

    Hier ein wenig mehr Code: http://rafb.net/paste/results/Rv386038.html

    Achja, der Code ist nicht von mir, sondern von Programmierern, welche schon
    lange nicht mehr in der Firma Arbeiten und ja, der Code wurde nie dokumentiert 😞

    mfg
    v R



  • virtuell Realisticer schrieb:

    Hier existiert doch 'm_param' auch schon, oder verwechsel ich hier irgendwas?

    hier initialisierst du m_param

    bei deinem anderen beispiel initialisierst du m_buf nicht.
    du nimmst zwar die adresse von m_buf und schreibst dann irgendwo irgendwas irgendwann hinnein. aber fuer den compiler ist diese variable uninitialisiert.

    deshalb setzt er, m_buf auf 0 - denn er will, dass alles initialisiert ist.
    laut seiner definition einer initialisierung ist m_buf nicht initialisiert (woher soll er denn wissen, dass du m_buf irgendwo einen wert zuweist und nicht nur die adresse speicherst um die variable referenzieren zu koennen?)



  • Hier existiert doch 'm_param' auch schon, oder verwechsel ich hier irgendwas?

    Ja. Du kannst nur eigene *Member* in der Initialisierungsliste initialisieren. Du kannst aber weder Member von abgeleieteten Klassen in Basisklassen initialisieren (wie hier), da sie zu diesem Zeitpunkt *noch nicht* existieren, noch kannst du Member von Basisklasse in abgeleiteten Klasse initialisieren, denn dort existiert das Element bereits. Wurde also schon initialisiert.


Anmelden zum Antworten