STL Debuging



  • ich hab mal ne Frage zum debugging beim VS2005 bei folgendem Quelltext:

    Wiso kann ich den Vector V1 beim Debugging nicht anschauen ???

    class Test
    {
    	char inhalt[6+1];
    
    public:
    	Test(void)
    	{
    		memset(inhalt,0,sizeof(inhalt));
    	}
    
    	void setInhalt(char *buff)
    	{
    		strcpy(this->inhalt,buff);
    	}
    	void print(void)
    	{
    		std::cout<<inhalt<<std::endl;
    	}
    };
    
    using namespace std;
    int main(void)
    {
    
    	vector<Test> V1;
    	list<Test> L1;
    
    	char buff[9];
    
    	Test * t;
    
    	for (int i=0;i<50;i++)
    	{
    		t = new Test();
    
    		wsprintf(buff,"NR%i",i);
    		t->setInhalt(buff);
    		V1.push_back(*t);
    
    	}
    
    	V1.at(1).print();
    
    	return 0;
    }
    


  • Was meinst du mit "nicht anschauen"?



  • ich kann die enthaltenen Werte beim Debugging nicht lesen <Bad Ptr> obwohl beispielsweise die ausgabe nicht funktioniert



  • Mal abgesehen von dem Problem würde ich ohnehin nicht Kopien der Objekte aus dem Heap speichern. Du kannst diese ja gar nicht mehr wieder freigeben, d.h. du hast ein riesen Speicherleck. Wenn dann lieber gleich Stackobjekte im Container speichern:

    using namespace std;
    int main(void)
    {
    
        vector<Test> V1;
        list<Test> L1;
    
        char buff[9];
    
        for (int i=0;i<50;i++)
        {
            Test t;
    
            wsprintf(buff,"NR%i",i);
            t.setInhalt(buff);
            V1.push_back(t);
        }
    
        V1.at(1).print();
    
        return 0;
    }
    

    So hast du dann wenigstens kein Speicherleck mehr.

    Greetz



  • Vellas schrieb:

    ...Du kannst diese ja gar nicht mehr wieder freigeben, d.h. du hast ein riesen Speicherleck. ...

    Obwohl wenn ich ebenfalls in diesem Fall (und auch sonst öfter) zu Stackobjekten rate, sehe ich nicht, wo da ein prinzipbedingt Speicherleck entstehen sollte. Er braucht nur ein delete einzufügen:

    ...
    int main(void)
    {
    ...
            Test * t;
    
            for (int i=0;i<50;i++)
            {
                    t = new Test();
                    wsprintf(buff,"NR%i",i);
                    t->setInhalt(buff);
                    V1.push_back(*t);
                    delete t; // hier
            }
    ...
    

    Nichtsdestotrotz ist Dein Code besser. 😉

    Gruß,

    Simon2.



  • hofburg87 schrieb:

    ich kann die enthaltenen Werte beim Debugging nicht lesen <Bad Ptr> obwohl beispielsweise die ausgabe nicht funktioniert

    Das die Ausgabe nicht funktioniert könnte eventuell am falschen Pointer liegen. Wenn der Debugger das nicht aufgelöst bekommt (tempaltes etc.) dann musst Du halt mal schauen was Du in die Routine reingibst.

    BadPointer zeigt der Debugger auch gerne mal an, wenn Du aus dem Adressbereich läufst und der Zeiter halt einfach fürn A.....hm naja, nicht zu gebrauchen ist.

    Generell geht aber genau das von Dir vorgestellte Beispiel prima:

    http://www.rothmichael.de/cpp/stl_debug.png



  • Ich habe bei VS2005 die Erfahrung gemacht, dass es reines Glück ist, ob in C++ beim Debuggen die Variablen angezeigt werden können oder nicht. Bisher habe ich noch nicht herausbekommen können, von welchen Faktoren das nun wirklich abhängt.



  • Probleme hatte ich bisher bei folgendem:
    Wenn die Variable nirgens verwendet wird, wie z.B. bei einem

    f1(T* e)
    {
      //...
    }
    

    und man e ansehen will.

    Ebenso muss man ab und an mal nachhelfen in dem man oben in der Eingabezeile den Typ anpasst.

    Dem ganzen sind natürlich Debuginfrmationen vorausgesetzt.



  • Simon2 schrieb:

    Vellas schrieb:

    ...Du kannst diese ja gar nicht mehr wieder freigeben, d.h. du hast ein riesen Speicherleck. ...

    Obwohl wenn ich ebenfalls in diesem Fall (und auch sonst öfter) zu Stackobjekten rate, sehe ich nicht, wo da ein prinzipbedingt Speicherleck entstehen sollte. Er braucht nur ein delete einzufügen:

    Das ist absoluter Schwachsinn, nur mit deinem delete wird der Programmcode auch nicht exception-safe. Da muss wenn dann ein scoped_ptr her!

    DerVollstreckerDer Vollstrecker



  • Der Vollstrecker schrieb:

    ...
    Das ist absoluter Schwachsinn, nur mit deinem delete wird der Programmcode auch nicht exception-safe. Da muss wenn dann ein scoped_ptr her!

    DerVollstreckerDer Vollstrecker

    Wer hat was von "exception-safety" geschrieben ?

    Ergo: Erst Lesen, dann Nachdenken, dann Posten.

    Simon2.

    P.S.: Und immer schön an Dieter Nuhr denken "Wer keine Ahnung hat: Einfach mal Fresse halten !"



  • Auch mit rommotzen bleibt die Tatsache, das bei auslösen einer Exception ein leak bleiben könnte.

    Jetzt bleibt aber die Frage ob push_back und die Benutzermethode eine Exception auslösen können.



  • Knuddlbaer schrieb:

    Auch mit rommotzen bleibt die Tatsache, das bei auslösen einer Exception ein leak bleiben könnte....

    Hat auch niemand bestritten.
    Ichhabe lediglich dem Eindruck widersprochen, mit "dem Anlegen auf dem Heap" entstünden "zwangsläufig Speicherleaks", weil:

    Vellas schrieb:

    ...Du kannst diese ja gar nicht mehr wieder freigeben, ...

    Wer also meint, dass diese Aussage stimmt (man kann diesen Speicher nicht mehr freigeben), mag die Hand heben.

    Gruß,

    Simon2.

    P.S.: Die verschiedenen Stufen der Exceptionsaftey sind mir ebenso bekannt wie diverse Konzepte, diese umzusetzen (z.B. scoped-Ptrs) - wer den Threadersteller darüber belehren möchte, darf das gerne tun (sollte sich aber überlegen, ob das für einen blutigen Anfänger jetzt das richtige Thema und der richtige Ton ist); bei mir ist der da an der falschen Adresse.



  • vector debuggen

    also das ist doch einfach - man kann wenn man will sich den kompletten vector anschaun - der "trick" dabei ist das man sich ein "Memory" window auf macht, und den first index des vectors aus der watchlist in das memory fenster rein zieht - dann sieht man was im speicher liegt, und es MUSS und wird immer funktionieren - amsonsten ist der vector leer {o;



  • Och ich entsinne mich daran, das Du in einem Beitrag in dem es um const char ging gleich etwas rund um strings gepostet hat.

    Zudem hat der Satz "Du kannst diese ja gar nicht mehr wieder freigeben" auch gültigkeit wenn eine Exception fliegt.

    Auch die Aussage "wo da ein prinzipbedingt Speicherleck entstehen sollte" passt die Antwort "Bei einer Exception" recht gut.

    Man kann aber auch gleich mit

    Ergo: Erst Lesen, dann Nachdenken, dann Posten.

    P.S.: Und immer schön an Dieter Nuhr denken "Wer keine Ahnung hat: Einfach mal Fresse halten !"

    um sich langen .

    Du solltest unbedingt mal ruhiger treten beim Posten 🤡 :xmas2:



  • Simon2 schrieb:

    Vellas schrieb:

    ...Du kannst diese ja gar nicht mehr wieder freigeben, d.h. du hast ein riesen Speicherleck. ...

    Obwohl wenn ich ebenfalls in diesem Fall (und auch sonst öfter) zu Stackobjekten rate, sehe ich nicht, wo da ein prinzipbedingt Speicherleck entstehen sollte. Er braucht nur ein delete einzufügen:

    ...
    int main(void)
    {
    ...
            Test * t;
    
            for (int i=0;i<50;i++)
            {
                    t = new Test();
                    wsprintf(buff,"NR%i",i);
                    t->setInhalt(buff);
                    V1.push_back(*t);
                    delete t; // hier
            }
    ...
    

    Nichtsdestotrotz ist Dein Code besser. 😉

    Gruß,

    Simon2.

    Stimmt, dass geht natürlich schon. Aber an sowas verkrüppeltes wage ich gar nicht zu denken. 😉

    Greetz



  • Mr Evil schrieb:

    und es MUSS und wird immer funktionieren

    Das ist so falsch. VS2005 ist in dieser Hinsicht einfach buggy.



  • Guten Abend,

    erstmal danke für eure hilfreichen Antworten! Ich habe mich beim 2. Post verschrieben. Die ausgabe geht jedoch nicht das besagte Debugging. Memory Fenster ist ein toller Tipp, den ich auch schon öfters angewendet habe (0x00400000 liegt die main und durchsteppen ist auch möglich ...) jedoch scheint mir das für eine Laufvariable wie beispielsweise einem iterator sehr ungeschickt und unproffesionell. Ist das sicher keine Einstellungssache oder wird man hier zum ddd gezwungen???

    zusätzliche Frage zum heap und stack object:

    nach dem Verlassen einer geschweiften Klammer ist doch Der Stack an der stelle wieder abgeräumt. Sogesehen wäre das doch die beste lösung oder ?



  • nach dem Verlassen einer geschweiften Klammer ist doch Der Stack an der stelle wieder abgeräumt. Sogesehen wäre das doch die beste lösung oder ?

    Ja, so hab ich es doch gemacht. In der Schleife habe ich eine lokales Objekt t angelegt und dann dem Vector hinzugefügt. Anschließend wird t automatisch destruiert und mit jedem Schleifendurchgang wird eine neue Variable t angelegt und am Ende zerstört. Wenn du es aber mit new machst, musst du es auch mit einem delete wie Simon2 es gemacht hat zerstören.

    Greetz



  • Ohne darauf herumreiten zu wollen, bei dem new-delete-Konstrukt muß entweder ein try-catch-Block drum herum gelegt oder (und das ist die bei weitem bessere Lösung) ein Smartpointer verwendet werden (zum Beispiel den bereits genannten aus Boost, std::auto_ptr würde es in diesem Fall aber auch tun).

    Ohne diese Konstrukte ist der Code nicht Exception-sicher. Das Argument, daß man jemanden, der gerade erst anfängt sich mit C++ zu beschäftigen (oder zumindest noch nicht viel Erfahrung damit hat), nicht mit Exceptions erschlagen sollte, kann ich nachvollziehen. Aber trotzdem bin ich der Meinung, daß man auch einer solchen Person keinen fehlerhaften Code vorsetzen sollte. Exception-Sicherheit ist keine zusätzliche Qualitätseigenschaft guten Codes. Sie ist elementar und ein Code der nicht Exception-sicher ist, ist fehlerhaft und somit im Allgeminen unbrauchbar.



  • Knuddlbaer schrieb:

    ...
    Du solltest unbedingt mal ruhiger treten beim Posten 🤡 :xmas2:

    Das stimmt wohl - aber bei mir macht auch der Ton die Musik.
    Wenn mich jemand anpampt, hat er gute Chancen, eine Replik im selben Tonfall zu bekommen.
    Wenn ich mit bei einem gemäßigtem Tonfall angesprochen werde, antworte ich meistens auch ruhiger.
    Eine große Hilfe dabei ist aber auch, wenn man Leute schon aus anderen Posts/Threads kennt, dann kann man ihre Denkweise besser einschätzen - Du bist mir z.B. permanent positiv aufgefallen (sorry, dass das jetzt gönnerhaft klingt; ist nicht so gemeint - finde gerade keine besseren Worte), so dass ich Kritik von Dir immer ernst nehmen würde. Und genau da sehe ich das Problem mit der "Unregistriertenpest" ( 😉 ), die hier ausgebrochen ist: Teilweise verhalten die sich hier wie die Sau im Dorfe, teilweise entsteht zumindestens der Eindruck, sie täten es und man hat keine Chance, das einzuordnen... 👎
    Wenn sie dann noch mit markiegen Nicknames hier auftauchen, drängt sich eher ein Eindruck auf, es ginge hier mehr um "trouble-making" als um "trouble-shooting" 😉

    Knuddlbaer schrieb:

    Och ich entsinne mich daran, das Du in einem Beitrag in dem es um const char ging gleich etwas rund um strings gepostet hat.
    ...

    Ich schätze, das bezog sich auf meine Anmerkung zum Thema "exception-safety für Anfänger" 😉 .... das meinte ich, wie ich es schrieb: Wer das machen möchte, darf das gerne tun, aber er
    - braucht nicht MICH damit (in diesem Thread) aufzuklären,
    - sollte sich didaktisch mehr aus dem Kreuz leiern als ein "Das ist absoluter Schwachsinn, nur mit deinem delete wird der Programmcode auch nicht exception-safe. Da muss wenn dann ein scoped_ptr her!" und
    - sollte vielleicht einen "einladenderen Schreibstil" wählen.
    -> So wie Z2 es z.B. gemacht hat. 😃

    Gruß,

    Simon2.


Log in to reply