wie finde ich fehler?
-
Falls das nicht helfen sollte: Vielleicht greifst du auch auf ein Objekt zu, das eigentlich schon zerstört ist, und du hast UB, was zufällig in dem, was du da bekommst, mündest. Was sagt der Entkäferer? Kannst du ein fehlerreproduzierendes Minimalbeispiel draus machen?
-
ich Tippe auf N::set(). Wenn diese Funktion pure virtual declariert ist dann kannst du sie nicht explizit aufrufen.
Kurt
-
ZuK schrieb:
ich Tippe auf N::set(). Wenn diese Funktion pure virtual declariert ist dann kannst du sie nicht explizit aufrufen.
KurtJein. Dann kann er keine Instanzen der Klasse erstellen, auch nicht von abgeleiteten Klassen, es sei denn sie definieren die Funktion. Der Compiler übersetzt sowas garnicht, der stellt sicher, dass die Methoden, die aufgerufen werden, immer existieren. Was der OP da hat ist ein Laufzeitfehler, den kanns nur mit viel Mühe geben

-
Ich hab´ mir mal irgendwann angewöhnt, rein virtuelle Methoden nicht direkt aufzurufen, sondern über eine konkrete Funktion der Basisklasse:
class AbstractClass { public: AbstractClass() { } virtual ~AbstractClass() { } unsigned int virtual_func() { return virtual_func_impl(); } private: virtual unsigned int virtual_func_impl() = 0; };Damit kann man zu Debug Zwecken einen Brechpunkt auf
virtual_funcsetzen und im Stack Trace nachschauen, wer wann die Methode aufruft, und ob es zu dem Zeitpunkt überhaupt zulässig ist.
-
Das nennt sich NVI.
-
Was der OP da hat ist ein Laufzeitfehler, den kanns nur mit viel Mühe geben

Hast recht, Gelingt mir jetzt auch nicht mehr.
Möglicherweise hangts auch von der compilerversion ab. Habs schon öfters geschafft.
Kurt
-
Geht doch ganz leicht.
Nämlich wenn im virtuellen destructor der Basisklasse die pure virtuelle Function indirekt aufgerufen wird. Bei direktem Aufruf gibts einen Linkerfehler
z.b.class N { public: virtual ~ N() { clear(); } void clear() { set(0); } virtual bool set(int what ) = 0 ; }; class A : public N { public: virtual bool set( int what ) { return true; } }; int main() { A a; }Kurt
-
Hallo zusammen,
also da staun ich ja nicht schlecht, wieviel Antworten hier meine Frage erzeugt. Also will ich mal versuchen mein bestes zu tun. Das Problem was ich habe, ist dass die Struktur doch sehr komplex ist. Daher hoffe ich, dass ihr mich versteht. Ok?
Also zu erst zu den Nachrichten:
Meine Basisklasse für Nachrichten ist MMessage, welche ein Serializable ist. Die Klasse Serializable verlangt, dass die Methode
virtual void set(Archive &archive) = 0;
implementiert wird. Diese wird beim Lesen und Schreiben des Archives aufgerufen, welches dann übers Netz gesendet wird bzw. von diesem empfangen wird. Serializable ist eine externe Bibliothek.
Nun erben von meiner Basisklasse MMessage über mehrere Zwischenstufen (als Beispiel):
MMessage --> MultMessage --> PeerMessage --> JoinAnnounce
Dann habe ich einen Dienst, welche sozusagen Nachrichten archiviert und diese dazu serialisiert. Der entsprechende Container heißt TransferMessage. TransferMessage sieht wie folgt aus:
class TransferMessage : public Serializable { public: ... virtual void set(Archive & archive){ archive(message); archive(time); } private: PeerMessage * message; VirtualLogicalTime time; }Es ist also selber serialisierbar und speichert eine PeerMessage. Wenn ich nun das Programm im Entkäferer aufrufe, dann komme ich an die Stelle:
archive(message);
Hier soll die spezifische JoinAnnounce Nachricht, welche die TransferMessage speichert archiviert werden. Über Stufen wird dann folgende Methode aufgerufen:
unsigned int Serializable::calcSerializedArraySize() { errorOccured = false; ByteArrayCalculator calc(swap); set(calc); return calc.getSerializedSize(); }Soviel wie ich verstehe, berechnet diese den notwendigen Platz im Archiv für die zu speichernde Nachricht. Und an der Stelle set(calc); kracht es dann mit der ursprünglichen Fehlermeldung. Hat dies überhaupt was mit mir zu tun? Oder ist dies ein Fehler in der Bibliothek????
Vielen Dank.
PS: Was heißt NVI???
Edit: Achso, neubauen hilft auch nicht. Ich habe den kompletten out Ordner gelöscht, alles das gleiche. Das Makefile wird bei jedem bauen automatisch erzeugt, von daher ... ???

-
uwerothfeld schrieb:
PS: Was heißt NVI???
lmgtfy

http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface
-
@uwe: Dann schau dir mal bitte die Anleitung zum Code posten in meiner Signatur durch und reduziere deinen Code so, dass du ihn komplett posten kannst, aber ohne den Fehler zu entfernen. Aus den paar Schnipseln sieht man jetzt keine auffälligen Stellen, wie das passieren kann.
-
hallo zusammen,
also das mit dem minibeispiel habe ich nicht hinbekommen, da ich aufgrund des verwendeten simulators und der libs zu viele abhängigkeiten hatte. aber ich habe den code deutlich reduziert und eingedampft und hart mit dem debugger gerungen und nun scheint es zu gehen. vielen dank für eure hilfe! da waren wertvolle hinweise dabei. eine frage hab ich allerdings noch: wenn der debugger mit fehler 139 abstürtzt, wenn man in eine funktion absteigen will, aber nicht, wenn man drüber läuft, woran liegt dies???
gruß und dank!
uwe
-
_uwerothfeld schrieb:
wenn der debugger mit fehler 139 abstürtzt, wenn man in eine funktion absteigen will, aber nicht, wenn man drüber läuft, woran liegt dies???
Das hört sich böse an. Benutzt du GDB und hast diesen Fehler: http://netbeans.org/bugzilla/show_bug.cgi?id=161992 ?
_uwerothfeld schrieb:
also das mit dem minibeispiel habe ich nicht hinbekommen, da ich aufgrund des verwendeten simulators und der libs zu viele abhängigkeiten hatte.
Tritt der Fehler nicht mehr auf, wenn du die lib-Aufrufe entfernst und die Lib-Header wegnimmst?
Hast du die Benutzung der Lib auch ordentlich weggekapselt?
-
hallo pumukl,
also das verhalten ist eigentlich wie in dem bug report beschrieben, aber komischerweise tritt er nur auf, wenn ich an der einen stelle ein "step into" mache. bei "step over" passiert nix. aber ich habe nun nochmals umgebaut und das Programm hat jetzt im Simulator einige runden erfolgreich absolviert. im datenspeicher sind die dateien auch gelandet. von daher hoffe ich, dass Problem gefixt zu haben. Mit der lib hatte der Fehler aber nix zu tun, das kam leider alles von mir :(. Wie kapselt man die Benutzung der lib richtig? Ich habe dies alles in einer Klasse, welche sozusagen als Wrapper/Adapter fungiert.
Netbeans nehm ich übrigends auch als IDE. Ich finde die super. Nur ab und an ärgert mich ein wenig die Codevervollständigung; da ist noch Nachholbedarf, finde ich. Aber im Vergleich zu Eclipse ist NB rattenschnell.

uwe
-
_uwerothfeld schrieb:
Wie kapselt man die Benutzung der lib richtig? Ich habe dies alles in einer Klasse, welche sozusagen als Wrapper/Adapter fungiert.
Das wäre dann richtig gekapselt

Für die Reduzierung deines Codes könntest du beispielsweise die echte Implementierung dieser Adapterklasse durch eine Mock-Klasse ersetzen, die einfach nur dummy-Werte zurückgibt, bzw. bei Laufzeiproblemen in jedem Aufruf das zurückgibt was die echte Implementierung zurückgeben würde.
-
hallo nochmal,
naja, durch die große vererbungskette allein in meinen nachrichten, ist da haufenweise code für die visualisierung und messung im simulator eingbaut. dies kann man sicherlich alles ersetzen, aber es würde nicht zu einer deutlichen verkürzung führen. auch ist es ein wenig ein henne ei problem. wie soll ich prüfen, ob das verkürzte protokoll den gleichen fehler im simulator erzeugt, wenn ich die für den simulator notwendigen schnittstellen abschneide??
wie auch immer, dank eurer hilfe habe ich es geschafft. daher nochmals an alle einen riesen dank. ist ein super forum hier!gruß
uwe