Speicher deallocieren bei dynamischen dreidimensionalem Array



  • Hallo erstmal. Ich habe heute ein programm geschrieben welches dynamisch ein
    dreidimensionales Array anlegt , etwas damit macht , das Ergebniss in Tabellenform ausgibt und danach den reservierten Speicher wieder freigeben soll.
    Habe ich alles gemacht - so weit , so gut...

    Meine Freage bezieht sich auf das de-allocieren des Speichers. Mir fällt leider keine Möglichkeit ein zu prüfen ob der Speicher wirklich freigegeben wurde wenn das Programm beendet wird. Es geht ja auch ohne. Ich poste hier also mal die wichtigen Teile des Codes :

    Hier lege ich das dynaimsche Array mit 3 Dimensionen an.

    int*** a = new int**[p];          //allocate Memory for the 3 dimensions p,q,r
    
    	for(i=0; i<p;i++)                   
    	{	
    		a[i] = new int*[q];
    
    		for(j=0;j<q;j++)
    		{
    			a[i][j]=new int[r];
    		}
    	}
    

    Dazwischen fülle ich es mit etwaigen Werten a[i][j][k] auf und gebe das Ganze aus. Jetzt kommt der springende Punkt :

    for(int j=0;j<p;j++)                  //dealocate the memory
    	{
    		for(int k=0;k<q;k++)
    		{
    			delete [] a[j][k];
    		}
    	}
    	delete [] a;
    

    Ist diese Sematik den Code zu löschen Korrekt ? Wie kann ich direkt testen ob der Speicher auch wirklich freigegeben wurde ? Jemand ne Idee ? Ich frage deshalb weil ich den Vorgang zwar für eindimensionale Arrays kenne, aber die Erweiterung auf dreidimensionale Arrays eher auf gut Glück vorgenommen habe.
    Danke schonmal im Voraus.



  • reicht hier nicht delete [] a; ?



  • Für jedes malloc ein free, für jedes new ein delete -> nein, deins reicht nicht aus.



  • daersc schrieb:

    reicht hier nicht delete [] a; ?

    Nein.

    Du musst jede deiner logischen Dimension einzeln freigeben, also a[j][k] , a[j] und ganz am Schluss auch a selbst. Wesentlich einfacher wäre es, die Dimensionslogik selbst zu programmieren, mittels Operatorüberladung kannst du dir diese Allokationen grösstenteils sparen. Sind das zufällig Übungsaufgaben zu einer Vorlesung? 😃



  • Du kannst dir überlegen, wie du den Speicher anforderst. Zuerst das äusserste Array. Dann für jedes Element wiederum ein Array, und so weiter. Jetzt schaust du, dass du innen mit löschen beginnst und in umgekehrter Reihenfolge wieder freigibst.

    Da es noch niemand erwähnt hat, kann ich ja mal die STL-Container erwähnen, damit spart man sich manuelle Speicherverwaltung und hat gerade noch einige praktische Operationen zur Verfügung. 😉

    Rachanol schrieb:

    Wie kann ich direkt testen ob der Speicher auch wirklich freigegeben wurde ? Jemand ne Idee ?

    Eben, versuch die Vorgehensweise nachvollziehen. Du kannst auch ruhig ein Blatt Papier nehmen und dir die Speicheranforderung grafisch darstellen. Aber manuelle Speicherverwaltung solltest du verstanden haben, das ist ein wichtiges Thema von C++, auch wenn man in der Praxis nicht sehr oft damit konfrontiert ist.



  • Danke für die Hilfe.

    Ich habe beim Aufbau also ein Array P mit der Dimension p.
    Dann p Arrays Q mit der Dimension q.
    Schlussendlich noch p mal q Arrays R mit der Dimansion r. -> "3D Würfel" aus zusammengesetzten kleinen Arrayelementquadern^^.

    Zuerst lösche ich also wieder die dritte gesamte Dimension r (delete[j][k]) , dann q (delete[k]) und am Schluss nochmal das einzelne array mit dim p per
    delete [] a. 💡



  • Was spricht eigtl ggn:

    int *a = new int[p*q*r];
    //früher a[x][y][z], jetzt:
    a[z + y*r + x*p*q]; //bin mir gerad nicht mehr ganz sicher, aber sollte nicht das problem sein, mal paar sekunden nachzudenken und zu probieren ^^
    delete []a;
    

    auf jeden fall würd ich das ganze in ne klasse kapseln, sonst hat man halt das prob, dass man bei den deletes nich mehr durchsieht - außerdem hat man so das prob (vorteil - je nach dem), dass man den speicher nicht am stück hat...

    bb



  • unskilled schrieb:

    Was spricht eigtl ggn:

    int *a = new int[p*q*r];
    //früher a[x][y][z], jetzt:
    a[z + y*r + x*p*q]; //bin mir gerad nicht mehr ganz sicher, aber sollte nicht das problem sein, mal paar sekunden nachzudenken und zu probieren ^^
    delete []a;
    

    auf jeden fall würd ich das ganze in ne klasse kapseln, sonst hat man halt das prob, dass man bei den deletes nich mehr durchsieht - außerdem hat man so das prob (vorteil - je nach dem), dass man den speicher nicht am stück hat...

    bb

    👍 👍 👍



  • Danke ! jetzt hats geklappt :
    So hab ichs gemacht :

    for(int i=0;j<p,j++)
    {
        for(int k=0;k<q;k++)
        {
            delete [] a[j][k];
        }
        delete [] a[j];
    }
    delete [] a;
    


  • Rachanol schrieb:

    Danke ! jetzt hats geklappt :
    So hab ichs gemacht :

    for(int i=0;j<p,j++)
    {
        for(int k=0;k<q;k++)
        {
            delete [] a[j][k];
        }
        delete [] a[j];
    }
    delete [] a;
    

    hättest dir auch ma meinen post durchlesen können 😛
    du kannst allein mal deine news+delete`s zählen und wirst merken, dass es doch ne ganze menge ist - im vrgl zu einem einzigen 😛
    und dann kannst du dir mal über die exception-sicherheit deines codes gedanken machen (jedes new kann fehlschlagen und du musst dann bereits bewilligten speicherplatz wieder freigeben).
    du könntest natürlich auch mal sagen, für was genau du das array brauchst (iwas mit tabelle und ausgeben - aber bissl genauer wär scho toll ^^)...
    ich vermute nämlich mal, dass es auch nen stl-container tut 😛
    auf jeden fall geht es mit sicherheit besser/eleganter/sicherer und vmrtl. auch schneller...

    bb


Log in to reply