Memory Leak und Strukturen?!?



  • Es wird immer so viel gelöscht wie allokiert wurde! Man kann beim Löschen nicht angegeben wieviel er löschen soll!



  • Wie kommst du auf die genauen Zahlen? Dem Taskmanager sollte man auch nicht alles glauben 😉 Wer weis was das BS da zwischendrin noch alles macht.



  • Paul_C. schrieb:

    EDIT: Hm, irgendwie gibt es dabei doch keinen Leak. Jedoch, wenn ich die Struktur in anderen Methoden nutze, dann gibt es welchen. Dabei passiert da nichts? Und seltsamerweise, wenn ich mir den Speicher anschaue, werden, wenn ich die Variable num freigebe wesentlich mehr Bytes gelöscht!?!

    Was machen denn diese anderen Funktionen mit der übergebenen struct?

    void init_struct(MyStruct& who)
    {
      who.len=100;
      who.num=new unsigned int[who.len];
    }
    

    ^^ sowas setzt den Zeiger 'who.num' auf eine neue Adresse -> der bisher verwendete Speicher ist unerreichbar geworden (=Leck)



  • Ok, bin von der Pause wieder da. 😉
    Also:

    @Jochen: mit deinem Leakfinder komme ich noch nicht ganz klar, wie muss man den benutzen?

    @codeman: len ist auf 2 gesetzt. 😉 Habe ich hier vergessen.

    @ Pellaeon: Ich schaue mir die Speicher vor und nach den deletes an. Und zwar an den Positionen der Variablen. Und ich schaue mir den Taskmanager an und stelle dann den Zuwachs fest.

    Zur Strukturerklärung:
    Diese Struktur repräsentiert im Endeffekt eine große Zahl.
    Die anderen Funktionen multiplizieren und dividieren diese Zahlen.

    Ein konkretes Beispiele wird schwierig, da diese Funktionen verschachtelt sind.
    Wenn ich beispielsweise 2 Zahlen in einer Schleife multipliziere. Passiert nichts. Wenn ich nur dividiere, passiert auch nichts. Wenn ich beides mache und auch nur nach ca. 130 Durchgängen, dann nutzt das Programm immer mehr Speicher. Bei einem Programm, was ständig läuft, wächst die Anzahl an MB sehr schnell.

    Ich hoffe, das ist ein wenig verständlich. 🙂
    Danke übrigens für eure bisherigen Antworten.



  • also generell ist das new und delete bei dir nicht falsch. Ich würd auch drauf tippen, was CStoll geschrieben hat. Irgendwo is ne Zuweisung auf den Zeiger und was geht verloren -> kannst ja mal std::vector benutzen anstatt das Feld selber zu verwalten.
    Ansonsten kanns u.U. auch an etwas ganz anderem liegen. WEnns nicht bis in 1 h fertig sein muss, lass den Code ruhen und schau morgen nochmal rein, evtl entdeckst dann etwas. Das hilf oft mal 🙂



  • Vielleicht solltest du darüber nachdenken, deiner struct noch einen Konstruktor und Destruktor zu spendieren:

    class MyStruct
    {
    public:
      MyStruct(unsigned int nlen=2)
       : len(nlen),num(new unsigned int[nlen])
      {}
      ~MyStruct()
      {delete[] num;}
    private:
      unsigned int len;
      unsigned int*num;
    }
    

    Bei deiner Fehlerbeschreibung deutet nämlich alles darauf hin, daß du irgendwelche temporären Objekte erzeugt und nicht ordnungsgemäß aufgeräumt hast:

    MyStruct mult(const MyStruct& l,const MyStruct& r)
    {
      MyStruct res;
      res.num=new[...];
      //...
      return res;
    }
    
    MyStruct s1,s2,s3;
    //belege s1, s2, s3 mit Werten
    MyStruct p=mult(s1,mult(s2,s3));
    //                 ^temp. Objekt - wird nicht gelöscht
    


  • Ja, aber ich wunder mich, dass bei den ersten 130 Durchläufen alles richtig aufgeräumt wird und danach nicht?
    Daher hatte ich gedacht, dass es an num liegt, da es auch dynamisch erzeugt wird. Und vielleicht gebe ich dieses falsch frei, so dass da immer ein Rest bleibt. Aber das wäre auch wieder unlogisch. Ach ja, und da dieser Teil des Programms nicht in C++ geschrieben werden darf, darf ich keine Klassen nutzen. 😞

    EDIT: Ok, das mit den 64 und 96 Bytes hat sich wohl geklärt. Wenn ich einfach

    int *myInt = new int;
    *myInt = 342345;
    delete myInt;
    

    schreibe sieht es so aus, als ob auch mehr als 4 Bytes gelöscht bzw. geändert werden! (Wenn man sich den Speicher anschaut). Auch wenn ich nicht weiß warum?



  • Welchen Speicher schaust Du denn an? Hoffentlich nicht im Task-Manager, da hier Default-Mässig nur das "Working-Set" angezeigt wird; was mit dem eigentlichen Speicher gar nichts zu tun hat!
    Blende bitte die Spalte "virtueller Speicher" ein, der zeigt den wirklichen Speicher an (oder im Perfmon die "Private Bytes").



  • oder lass es im debugger laufen. wenn du das programm beendest zeigt der dir memory leaks an. wenn der nichts anzeigt sind höchstwahrscheinlich auch keine da.



  • Also, wenn ich debugge, dann schaue ich unter Debug->Windows->Memory mir an, was nach dem delete passiert. Da habe ich dann gesehen, dass sich auch die Bytes drumherum alle ändern. Das scheint aber wohl normal zu sein.

    Beim Taskmanager schaue ich parallel nach, wieviel Speicher das Programm gerade benutzt. @Jochen: die Optionen, welche du beschrieben hast, finde ich aber nicht beim Task Manager?!? EDIT: Hab's gefunden. 🙂

    @net: Das ist es ja. Visual Studion meckert nicht.

    MfG,
    Paul.

    EDIT2: Ok, VM-Size wächst definitiv.



  • Paul_C. schrieb:

    Ach ja, und da dieser Teil des Programms nicht in C++ geschrieben werden darf, darf ich keine Klassen nutzen. 😞

    wenn es kein C++ sein darf, fällt auch new/delete aus...

    ohne genügend quellcode kannst hier genausogut volkards glaskugel fragen.



  • Paul_C. schrieb:

    Ach ja, und da dieser Teil des Programms nicht in C++ geschrieben werden darf, darf ich keine Klassen nutzen. 😞

    wenn es kein C++ sein darf, fällt auch new/delete aus...

    ohne genügend quellcode kannst hier genausogut volkards glaskugel fragen.



  • Nimm einfach mal die CMemoryState Klasse, die sagt dir genau wieviel und in welchen Speicherheap dein leck ist.

    So in etwa hatte ich es mal implementiert:

    #if defined(_DEBUG)
    	CMemoryState diffMemState;
    
    	newMemState.Checkpoint();
    	if(diffMemState.Difference( oldMemState, newMemState )) diffMemState.DumpStatistics();
    #endif 
    }
    

    Du brauchst allerdings die atlsession.h für die Unterstützung.
    Sollte aber kein porp. sein. Ansonsten musst du halt noch andere basis atl header includieren. Da du ja keine Klassen verwenden darfst/willst kannst dus ja mal temporär einbinden um das leck zu finden und nachher wieder raus machen. 😉

    EDIT: Erklärungen yur Klasse findest du hier: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmfc98/html/_mfc_cmemorystate_class_members.asp

    codeman



  • camper schrieb:

    Paul_C. schrieb:

    Ach ja, und da dieser Teil des Programms nicht in C++ geschrieben werden darf, darf ich keine Klassen nutzen. 😞

    wenn es kein C++ sein darf, fällt auch new/delete aus...

    ohne genügend quellcode kannst hier genausogut volkards glaskugel fragen.

    ja, im eigentlichen Programm ist das auch mit malloc() realisiert.
    Finde hier new/delete 'übersichtlicher'. (ok, bin nur schreibfaul).

    Ok, mal sehen, was ich mit der Klasse machen kann.
    Danke. Melde mich wieder. 😉



  • Wenn du keine Klassen verwenden darfst, mußt du selber dafür sorgen, daß nirgends ein Zeiger verloren geht (am besten geht das, indem deine Operatoren die verwendbaren Structs von außen bekommen):

    void mult(MyStruct l,MyStruct r,MyStruct* ret)
    {
      assert(ret!=NULL);
      ret->len=l.len+r.len;
      if(ret->num!=NULL)
        free(ret->num);
      ret->num=malloc(ret.len*sizeof(unsigned int);
      //fülle ret->num
    }
    
    MyStruct a,b,c;
    //fülle a und b
    mult(a,b,&c);
    


  • @CStoll: so ähnlich mache ich das auch. 😉

    Zur CMemoryState: Der gibt mir auch kein Memoryleak, aber der Task Manager sagt was anderes. Man kann auch erkennen, dass da auch immer wieder mal was freigegeben wird. Momentan springt der VM-Size zwischen ca. 2000 KB und 4000 KB, und wächst stetig ein wenig. 😕



  • Habe nun ca. 10 Minuten das Programm laufen lassen. Zuerst sah es so aus, als ob es sich bei ca. 4500 KB einpendeln würde. Dann nach 7 Minuten plötzlich ein Sprung auf 55000 KB! Und dort verblieb es dann.



  • Solange du am Programmende alles wieder freigegeben bekommst, ist es kein Leck 😉 Es kann höchstens sein, daß der Heap-Manager sich gleich etwas mehr Speicher reserviert als er wirklich benötigt (dafür kann er den nächsten new/malloc dann aus seinen Reserven bedienen).



  • Na gut, dann belasse ich es vorerst dabei.
    Ein großes DANKESCHÖN! 😃

    MfG,
    Paul.


Anmelden zum Antworten