Stack versus Heap

Sollte man Objekte lieber auf dem Stack oder dem Heap anlegen? Um diese Frage zu beantworten, betrachten wir die verschiedenen Speicher einmal genauer.

Stack ist der gängigste Speicher. int a; - a liegt auf dem Stack. Wenn der Scope verlassen wird, dann wird a zerstört. Objekte auf dem Stack zu erzeugen ist normalerweise viel schneller als sie dynamisch auf dem Free Store oder dem Heap anzulegen. Der Nachteil des Stacks ist, dass seine größe arg begrenzt ist - unter Linux sind es zB meistens 8 Megabyte. Die Größe ist aber einstellbar. Ein weiterer Nachteil ist, dass man nicht selber die Lebensdauer eines Objektes bestimmen kann (dies kann man aber auch als Vorteil sehen).

Der Heap und der Free Store sind dynamische Speicher. Wir können mittels new Objekte auf dem Free Store anlegen und die Lebenszeit selber bestimmen. Der Heap wird über die C Funktionen malloc, calloc und realloc angesprochen - er kann deswegen getrost ignoriert werden, da man diese Funktionen in C++ nicht verwenden sollte. Weiters bietet der Free Store nahezu unendlich Speicher - auf einem 32Bit System (wie zB Windows oder Linux) kann man theoretisch 4GB an Speicher anfordern. Praktisch gesehen wird das natürlich nicht gehen ;).

Sollten wir nun unsere Objekte auf dem Free Store oder auf dem Stack anlegen? Am besten legen wir sie am Stack ab - denn der ist schneller als der Free Store. Es gibt wenige Ausnahmen in denen der Free Store besser ist - nämlich dann, wenn das Objekt wirklich sehr groß ist. Man beachte aber, dass bei folgendem Code lediglich sizeof(int)+sizeof(int*) Bytes auf dem Stack liegen - der Rest dynamisch am Free Store.

    #include <iostream>
    using namespace std;

    class Array
    {
    private:
      int size;
      int* array;

    public:
      Array(int size)
      : size(size), array(new int[size])
      {}

      ~Array()
      {
        delete [] array;
      }

      int& get(int index)
      {
        return array[index];
      }
    };

    int main()
    {
      Array a(1000);
      a.get(2)=7;
    }

    

Wir sehen hier auch gleich eine Implementierung des RAII (Resource Acquisition Is Initialization) Idioms. Wir legen ein Objekt auf dem Stack an, dass beim Initialisieren eine Ressource (zB Speicher) anfordert und beim Zerstören (out of scope gehen) diese Ressource wieder freigibt. Es kann somit zu keinen Speicherlöchern (Memory / Resource Leaks) kommen, da der Destruktor garantiert aufgerufen wird.

Das RAII Idiom wird in C++ eigentlich immer verwendet, wenn man Ressourcen beschafft, die man wieder freigeben muss. zB verwendet man Smart Pointer (wie zB std::auto_ptr) um Speicher sicher zu verwalten.

Deine Aufgabe ist es jetzt, eine kleine String-Klasse zu schreiben. Denke dabei an C String Handling und an das RAII Idiom.

Hier ist die Lösung

top