c++ programme - Wann ist es am besten, den Stack anstelle des Heaps zu verwenden und umgekehrt?




4 Answers

Verwenden Sie den Stapel, wenn Ihre Variable nicht verwendet wird, nachdem die aktuelle Funktion zurückgegeben wurde. Verwenden Sie den Heap, wenn die Daten in der Variablen über die Lebensdauer der aktuellen Funktion hinaus benötigt werden.

programming beispiel

Wann ist es in C ++ am besten, den Stack zu verwenden? Wann ist es am besten, den Heap zu verwenden?




Verwenden Sie den Stapel, wenn der verwendete Speicher streng auf den Bereich beschränkt ist, in dem Sie ihn erstellen. Dies ist nützlich, um Speicherlecks zu vermeiden, weil Sie genau wissen, wo Sie den Speicher verwenden möchten, und Sie wissen, wann Sie ihn nicht mehr benötigen, damit der Speicher für Sie aufgeräumt wird.

int main()
{ 
   if (...)
   {
      int i = 0;
   }
   // I know that i is no longer needed here, so declaring i in the above block 
   // limits the scope appropriately
}

Der Heap ist jedoch nützlich, wenn auf Ihren Speicher außerhalb des Erstellungsbereichs zugegriffen werden kann und Sie keine Stapelvariable kopieren möchten. Dies kann Ihnen explizite Kontrolle darüber geben, wie Speicher zugewiesen und freigegeben wird.

Object* CreateObject();

int main()
{
    Object* obj = CreateObject();
    // I can continue to manipulate object and I decide when I'm done with it

    // ..
    // I'm done
    delete obj;
    // .. keep going if you wish
    return 0;
}

Object* CreateObject()
{
   Object* returnValue = new Object();
   // ... do a bunch of stuff to returnValue
   return returnValue;
   // Note the object created via new here doesn't go away, its passed back using 
   // a pointer
}

Offensichtlich ist es ein häufiges Problem, dass Sie vergessen, Ihr Objekt zu löschen. Dies wird als Speicherleck bezeichnet. Diese Probleme treten häufiger auf, da Ihr Programm immer trivialer wird, wo "Ownership" (oder wer genau für das Löschen von Dingen verantwortlich ist) schwieriger zu definieren ist.

Gängige Lösungen in besser verwalteten Sprachen (C #, Java) sind die Implementierung der Garbage Collection, sodass Sie nicht über das Löschen von Dingen nachdenken müssen. Dies bedeutet jedoch, dass sich etwas im Hintergrund befindet, das aperiodisch ausgeführt wird, um Ihre Heap-Daten zu überprüfen. In einem nicht-trivialen Programm kann dies ziemlich ineffizient werden, wenn ein "Garbage Collection" -Thread erscheint und nach Daten sucht, die gelöscht werden sollen, während der Rest Ihres Programms blockiert wird.

In C ++ ist die gängigste und beste (meiner Meinung nach) Lösung, um mit Speicherlecks umzugehen, ein intelligenter Zeiger. Die gebräuchlichste davon ist boost::shared_ptr was ist ( Referenz gezählt )

Also um das obige Beispiel neu zu erstellen boost :: shared_ptr CreateObject ();

int main()
{
    boost::shared_ptr<Object> obj = CreateObject();
    // I can continue to manipulate object and I decide when I'm done with it

    // ..
    // I'm done, manually delete
    obj.reset(NULL);
    // .. keep going if you wish
    // here, if you forget to delete obj, the shared_ptr's destructor will note
    // that if no other shared_ptr's point to this memory 
    // it will automatically get deleted.
    return 0;
}

boost::shared_ptr<Object> CreateObject()
{
   boost::shared_ptr<Object> returnValue(new Object());
   // ... do a bunch of stuff to returnValue
   return returnValue;
   // Note the object created via new here doesn't go away, its passed back to 
   // the receiving shared_ptr, shared_ptr knows that another reference exists
   // to this memory, so it shouldn't delete the memory
}






Verwenden Sie den Heap, um nur Speicherplatz für Objekte zur Laufzeit zuzuweisen. Wenn Sie die Größe zum Zeitpunkt der Kompilierung kennen, verwenden Sie den Stapel. Anstatt Heap-allokierte Objekte von einer Funktion zurückzugeben, übergeben Sie einen Puffer in die Funktion, in die geschrieben werden soll. Auf diese Weise kann der Puffer zugewiesen werden, wo die Funktion als ein Array oder eine andere stack-basierte Struktur aufgerufen wird.

Je weniger malloc () -Anweisungen Sie haben, desto weniger Möglichkeiten für Speicherlecks.




Related

c++

Tags

c++