In C verwendet man eine der Funktionen malloc(), calloc() und realloc(), um Speicher aus dem Heap zu allokieren, und bis zu einem passenden Aufruf von free() nach Gutdünken zu verwenden.
In C++ hat man diese Möglichkeit auch noch. Es gibt aber einen Ersatz dafür, der meistens auch genutzt werden sollte: new und delete.
Zum Allokieren eines Objekts oder eines Feldes davon verwendet man
jetzt
new Objekttyp
um ein Objekt vom
Typ Objekttyp zu allokieren, oder
new Objekttyp[
Anzahl]
um ein Feld mit Anzahl Elementen jeweils vom
Typ Objekttyp zu allokieren.
Je nach dem, ob man ein Element oder ein Feld allokiert hatte, kann
man den Speicher mit delete
oder mit delete[]
wieder
freigeben.
Beispiel im C-Stil:
// Zeiger auf ein Element int *p1; // Zeiger auf viele Elemente int *pviele; // allokiert Platz für 1 int, und liefert Zeiger darauf p1 = (int*)malloc( sizeof(int) ); if( p1==NULL ) { /* Fehlerbehandlung, Programmabbruch */ } // allokiert Platz für 500 int, und liefert Zeiger darauf pviele = (int*)malloc( 500*sizeof(int) ); if( pviele==NULL ) { /* Fehlerbehandlung, Programmabbruch */ } // Speicher verwenden... *p1 = 25; pviele[0] = 1; // ... pviele[499] = 500; // Speicher für 1 Element freigeben free( p1 ); // Speicher für Feld freigeben free( pviele );
Im C++-Stil sieht das selbe so aus:
// Zeiger auf ein Element int *p1; // Zeiger auf viele Elemente int *pviele; // allokiert Platz für 1 int, und liefert Zeiger darauf p1 = new int; // allokiert Platz für 500 int, und liefert Zeiger darauf pviele = new int[500]; // Speicher verwenden... *p1 = 25; pviele[0] = 1; // ... pviele[499] = 500; // Speicher für 1 Element freigeben delete p1; // Speicher für Feld freigeben delete[] pviele;
Dabei muß man folgende Unterschiede unbedingt kennen:
(
Objekttyp*)
konvertiert ist).
Man muß demnach nicht explizit casten.
new dagegen liefert immer einen gültigen Zeiger, oder wirft im
Fehlerfall eine Ausnahme (vom Typ bad_alloc
, siehe
Ausnahmebehandlung
und
Ausnahmen der Standardbibliothek).
Dadurch erspart man sich die Mühe, nach jedem Allokieren den Rückgabewert prüfen zu müssen. Gegebenenfalls muß man stattdessen mit einem try-Block die Ausnahme abfangen.
new dagegen kennt den Typ, und kann deshalb den beschafften Speicherplatz gleich sinnvoll initialisieren, indem für Klassenobjekte der zugehörige Konstruktor aufgerufen wird (siehe Konstruktoren, Destruktoren).
Ebenso kann free() nur den Speicherbereich wieder freigeben,
während delete und delete[]
gegebenenfalls für jedes
Objekt den passenden Destruktor aufrufen.
Was man weiterhin beachten muß:
delete[]
freigeben.
[]
!) verwenden.
Ebenso
umgekehrt: hat man ein Feld allokiert
(new Objekttyp[
Anzahl]
, auch wenn
Anzahl gleich eins ist), dann darf man nur mit delete[]
den Speicher wieder freigeben.
AnyWare@Wachtler.de