Visual Studio macht probleme



  • Und was soll ich jetzt machen ? Bei mir im Code sind sie ja definiert wenn ich sie als parameter übergebe, von daher weiß ich auch nicht..



  • Bob Wolfskin schrieb:

    Wenn ich jetzt von B aus _parent->MakeThis(this); schreibe bekomme ich bei der auswertung der Funktion MakeThis ein nullptr als paramter

    Bob Wolfskin schrieb:

    Bei mir im Code sind sie ja definiert wenn ich sie als parameter übergebe,

    Irgendwas von beiden Aussagen kann nicht stimmen.

    Bob Wolfskin schrieb:

    Und was soll ich jetzt machen ?

    Code mit nachvollziehbarem Crash posten.



  • Bob Wolfskin schrieb:

    Wenn ich jetzt von B aus _parent->MakeThis(this); schreibe bekomme ich bei der auswertung der Funktion MakeThis ein nullptr als paramter, was eigendlich nicht sein kann.

    Warum? this kann schon null sein. Dann hast du den Fehler eben weiter oben im Callstack. Kann man so pauschal aber gar nicht sagen, wo der Fehler liegt, gibt viele Möglichkeiten. Ich kann nur ziemlich sicher ausschließen, dass Visual Studio oder sonst was schuld ist.
    Dass Fehler im Release auftreten im Debug nicht, ist jetzt auch nicht so ungewöhnlich.



  • Hmmm also das mit dem Codebeispiel ist sehr schwer zu machen, weil es wie gesagt ein sehr großes Projekt ist.

    Aber z.B zeigt er mir jetzt an ,dass wenn ich ein button in meinem Menu drücke, der IComponentManager ( das ist der Manager wo alle Systeme verwalten werden ) bzw. seine ganzen Member ( in dem Fall sind es alle Systeme ) auf garnichts zeigen.

    Dass kann ja garnicht sein, 1. der button sowas von überhauptnichts damit zu tun hat was in dem Componentmanager passiert und 2. das Programm ja bis dahin lief ??

    Also weiß ich echt nichts mehr.

    http://s14.directupload.net/file/d/3127/83lk6evw_jpg.htm



  • this == nullptr impliziert, dass die Memberfunktion auf keinem gültigen Objekt aufgerufen wird, sondern auf einem dereferenzierten Nullzeiger, was UB ist. Wie gesagt musst du also weiter oben schauen, wo ein Nullzeiger übergeben wurde.

    Bob Wolfskin schrieb:

    Aber z.B zeigt er mir jetzt an ,dass wenn ich ein button in meinem Menu drücke, der IComponentManager [...] bzw. seine ganzen Member [...] auf garnichts zeigen.

    Das weist darauf hin, dass der IComponentManager selbst ungültig ist. Er hat mit 0x848 auch eine ungewöhnlich tiefe Adresse. Gib aber nächstes Mal bitte direkt den Link zum Bild an: http://s14.directupload.net/images/130106/83lk6evw.jpg

    Bob Wolfskin schrieb:

    Dass kann ja garnicht sein, 1. der button sowas von überhauptnichts damit zu tun hat was in dem Componentmanager passiert und 2. das Programm ja bis dahin lief ??

    Undefiniertes Verhalten: Du hast einen Bug an Stelle A im Programm. Meistens läuft alles rund, aber ab und zu werden Daten auf merkwürdige Weise an Stelle B verändert. Solche Bugs sind extrem mühsam zu finden.

    Besser, du beugst ihnen vor, indem du High-Level-Sprachkonstrukte verwendest (Smart-Pointer oder STL-Container statt new / delete ) und ab und zu assert() in deinen Code schreibst.



  • Besser, du beugst ihnen vor, indem du High-Level-Sprachkonstrukte verwendest (Smart-Pointer oder STL-Container statt new/delete) und ab und zu assert() in deinen Code schreibst.

    Ich benutze aber für alle Memebrvariablen, die als Pointer gelten sollen Smart-Pointer -> unique_ptr.Vielleicht wird ja irgendwo der Bereich verlassen, und die Smart-pointer löschen die instanz.



  • Also ich würde da noch gerne was fragen.
    Wenn ab und zu mal ein pointer falsch übergeben wird ( also ein nullptr) was genau heißt dass dann ?
    Es tritt nämlich machmal auf was ich unten mit klasse A und B gemeint habe.



  • Bob Wolfskin schrieb:

    Ich benutze aber für alle Memebrvariablen, die als Pointer gelten sollen Smart-Pointer -> unique_ptr.Vielleicht wird ja irgendwo der Bereich verlassen, und die Smart-pointer löschen die instanz.

    Irgendwo ist genau da, wo deine IGameManager-Instanz zerstört wird (oder wo du reset() aufrufst - dann wäre die 0x00000848-Adresse aber auch auf deinem Mist gewachsen). Es erscheint wahrscheinlicher, dass zu irgendwo über Arraygrenzen hinausschreibst oder ähnliches, wie Nexus schon gesagt hat.

    Beherzige auch den Hinweis mit assert - überall, wo die Korrektheit deines Code von einer Bedingung abhängt, die zwar von deiner Programmlogik her zu diesem Zeitpunkt erfüllt sein sollte, aber es nicht offensichtlich ist, dass sie auch erfüllt ist, da kommt ein assert hin. Das hat mir früher sehr geholfen und in gewissem Maß auch heute noch.

    Wenn ab und zu mal ein pointer falsch übergeben wird ( also ein nullptr) was genau heißt dass dann ?

    Es ist nicht falsch, nullptr zu übergeben. Es ist aber falsch, diesen Zeiger zu dereferenzieren.



  • Moment ich habe gerade was festgestellt.Ich habe einfach vor dem Aufrug von _parent->ChangePane(it->second); (siehe Bild) so ein Debug Punkt gesetzt.
    An dem Zeitpunkt ist this okey.
    Wenn ich mir ohne den Debupg point den Fehler anzeigen lasse, ist this nicht mehr in Ordnung, also liegt es wohl an diesem Aufruf.



  • Sind _parent und it gültig?



  • Ich sehe gerade _parent ist ungültig, obwohl es ein member ist ?



  • Dann verfolge _parent weiter im Debugger. Speziell die Initialisierung, aber auch danach.



  • Sollte ich _parent nicht als Referenz erstellen ?



  • Die Initialisierung sieht nicht falsch aus:

    Hier wird das _parent in den Konsturktor übergeben:

    IResult IMenuSystem::Initialize()
    {
    	//....
    	IMenuPane* _pmain = new IMenuPane(FindChild(_sMenuScene,"menu_main"),this);
    

    und so sieht der Konstruktor aus:

    IMenuPane::IMenuPane(TEntity node,IMenuSystem* parent) : _parent(parent)
    {
    	_camNode = node;
    	_state = P_NONE;
    
    }
    


  • Jetzt komm ich der Sache schon näher:

    void IMenuPane::ButtonSignal(IMenuButton* b )
    {
    	if(b)
    	{
    	std::map<IMenuButton*,IMenuPane*>::iterator it; // Hier ist _parent noch okey
    	for(it = _mButtonSignals.begin(); it != _mButtonSignals.end(); it++)
    	{
    		if(it->first == b )
    		{
    			_parent->ChangePane(it->second);  // Hier nicht mehr
    			break;
    		}
    	}
    	}
    
    }
    

    Wie kann das sein, dass sich _parent hier verändert ? Es wird ja nicht aufgerufen, auch wird nichts mit dem Objekt gemacht



  • So habe das glaub ich jetzt gelöst, einfach _parent durch it->second->_parent ersetzt.Jetzt bekomme ich wieder diesen Fehler wie auf dem Bild.

    Ich weiß auch garnicht was dort der Fehler sein soll.IGameManager ist eingendlich so eine Art interface pattern, was einfach als einzigen Member einen IComponentManager hat und diesen einfach Updatet,Initialisiert,Löscht.

    Dieser wird auch niergendwo übergeben.



  • OHHHHHHHHHHHHHH GOTT dieses Scheiß Programm.
    Immer wieder dieses Problem mit _parent, diesmal is this undefiniert.....WTF
    Das Programm ist schon seit 2 Monaten am Laufen und ich hatte wirklich noch nie Problemme damit, dass ohne VS 2010 laufen zu lassen, ich glaube ich lass es einfach und mach normal weiter.

    Mal gucken, wenn ich morgen nichts finde dann weiß ich auch nicht....



  • Bob Wolfskin schrieb:

    Wie kann das sein, dass sich _parent hier verändert ?

    Das fragst du am besten ChangePane()...

    Bob Wolfskin schrieb:

    So habe das glaub ich jetzt gelöst, einfach _parent durch it->second->_parent ersetzt.

    Naja, entweder es gibt eine gute Begründung, warum das vorher falsch war und nun richtig ist, oder die Änderung ist falsch.

    Sinn und Zweck der ButtonSignal()-Funktion ist mir auch nicht ganz klar. Sieht auf den ersten Blick so aus, als wäre das designmäßig eher von hinten aufgezäumt. Ein Klick auf einen Menu-Button führt dazu, dass alle Menu-Panes gefragt werden, ob sie denn nicht mal das zum Button gehörige Menu-Pane aktivieren könnten, oder wie muss man das verstehen?



  • Es soll so funktionieren:

    Auf einem Pane sind Buttons.(Ah ja es ist ein 3D Menu)
    Die Panes stehen für Menüabschnitt wie Main-Menu,Options.....

    Im IMenuSystem werden alle Panes und Komponenten erstellt.( Polymoph, alle Komponenten haben die klasse IComponent, jedoch können sie von den Klassen IMenuButton,IMenuSlider... sein).

    Man fügt also einem Button ein singalpane hinzu, d.h wenn man auf diesen Button drückt, soll der zum diesem Pane wechseln.

    Man fügt dem Button also mit SetButtonSignalPane das erwünschte Pane hinzu, was in einer map gespeichert wird ( diese map ist member von IMenuSystem).
    Wird jetzt auf ein Button geklickt ruft er IMenuPane::ButtonSignal(this) auf.
    Dort wird dann geguckt ob es du diesem Button ein Signal gibt ( ein IMenuPane). Wenn ja soll durch das IMenuSystem zum diesem Pane gewechselt werden.
    Tada 🙂

    Ah ja hier ist eine etwas ältere version davon:
    http://www.youtube.com/watch?v=ALLm0MOijME



  • Bob Wolfskin schrieb:

    ich glaube ich lass es einfach und mach normal weiter.

    Davon würde ich abraten. Wenn du einem Bug auf der Spur bist, und besonders wenn es sich um UB handeln könnte, merze ihn so schnell es geht aus! Sonst wird dir das mit Sicherheit eines Tages zum Verhängnis...

    Du debuggst schon im Debug-Modus und hast alle Debug-Symbole aktiviert? Nur um offensichtliche Fehler auszuschliessen...


Anmelden zum Antworten