Wie räume ich richtig hinter mir auf?



  • Hallo Community!

    Ich habe hier folgendes Minimalbeispiel:

    Eingabe: s vom Typ int
    
    test = new float**[s];
    for (int x = 0; x < s; x++)
    {
       test[x] = new float*[s];
       for (int y = 0; y < s; y++) neighborhood[x][y] = new float[s];
    }
    

    Wie kann ich diesen Speicher am Ende richtig aufräumen, sodass ich keine Speicherlöscher erzeuge?

    Viele Grüße



  • Indem Du std::vector und keine rohen Zeiger benutzt.



  • Für jedes new[] wird ein delete[] fällig. Allerdings solltest du immer, wenn du new[] und delete[] einsetzen willst, dich fragen, ob es wirklich eine gute Idee ist, das zu tun; denn statt

    void foo()
    {
      int* ptr = new int[123];
      ...
      delete[] ptr;
    }
    

    ist folgendes einfacher und weniger fehleranfällig:

    void foo()
    {
      std::vector<int> vec (123);
      ...
    }
    

    siehe
    http://de.wikipedia.org/wiki/Ressourcenbelegung_ist_Initialisierung

    Viele solcher Klassen gibt es ja schon in der Standardbibliothek (stream-Klassen , STL-Container, etc etc etc). Und falls du eine solche selbst bauen willst, solltest du noch
    http://de.wikipedia.org/wiki/Dreierregel_(C%2B%2B)
    gelesen haben.



  • Danke für die Antworten. Das hab ich befürchtet. Dadurch wird der Zugriff aufwändiger.



  • host schrieb:

    Dadurch wird der Zugriff aufwändiger.

    Wieso?



  • Da es hier um eine Art Würfel geht, werf ich mal Boost.Multi-Array in die Diskussion.

    test = new float**[s];
    for (int x = 0; x < s; x++)
    {
       test[x] = new float*[s];
       for (int y = 0; y < s; y++) neighborhood[x][y] = new float[s];
    }
    

    So jedenfalls sollte man das schon deshalb nicht machen, weil new std::bad_alloc werfen kann und man ggf. hinterher nicht mehr weiß, bis wohin man schon Zeiger auf Speicher hat, der wieder freigegeben werden muss. Man könnte dieses spezielle Problem zwar mit

    test[x] = new(std::nothrow) float*[s];
    if(test[x]) {
      for(int y = 0; y < s; ++y) {
        neighborhood[x][y] = new(std::nothrow) float[s];
      }
    }
    

    o.ä. umschiffen, aber die Fehlerbehandlung wäre immer noch ausgesprochen widerlich. Dagegen ist

    #include <boost/multi_array.hpp>
    
    ...
    
    boost::multi_array<float, 3> test(boost::extents[s][s][s]);
    

    gleich vernünftig verRAIIt.


Anmelden zum Antworten