New Operator

Hallo zusammen.

Ich versuche gerade mein Wissen in c++ zu erweitern.

So nun bin ich auf den new Operator gestossen.

In dem Beispiel wird gesagt das man denn new Operator bei Feldern einsetzen kann.

Mir ist nicht ganz klar wo der Unterschied zu einer „normalen“ Feld Definition liegt?

z.B:
int feld[100];
int *p=feld;
// Befehle verstehe ich

int *p;
p= new int[100];
// So hier habe ich nun einen Pointer der auf das erste Feld zeigt.

Was mir auffällt ist das das Feld mit new keinen Namen hat nur einen pointer.

Ich verstehe nicht was das für Vorteile bringen soll?

Ich habe noch die Aussage das die Variablen dynamisch zur Laufzeit angelegt werden.

Was bringt das?
Wenn ich ein neues Feld brauche definiere ich eins.

Kann mir jemand eine Erklärung geben oder ein Beispiel!

Mfg spongebob

Erklärung
Funktional unterscheiden sich beide Arrays nicht, vielmehr verwenden sie unterschiedliche Arten von Speicher zur Arbeit. Mit „int arr[10];“ legst du ein Feld auf dem Stack-Speicher an. Stack-Speicher ist billig und bevorzugend zu verwenden. Gravierender Nachteil von Stack-Speicher ist die Tatsache, dass er mit dem Verlassen des Scopes (der Funktion, des umschliessenden {}-Blocks) automatisch wieder freigegeben wird und man nicht mehr darauf zugreifen darf.
Mittels new und delete übernimmst du die Verantwortung für den Speicher und bestimmst wann dieser wieder freigegeben wird. new allokiert vom Heap-Speicher, dieser ist teurer als der Stack-Speicher, dafür bleibt er solange gültig, bis du ihn frei gibst.

int i; // stack
int*i = new int; // heap

int i[10]; // stack
int*i = new int[10]; // heap

Gruß Markus

Hi spongebob!

Was Markus über Heap und Stack geschrieben hat, ist richtig. Aber er hat meiner Meinung nach etwas sehr wichtiges nicht aufgeführt: Mit new werden dynamischen Arrays erstellt. Das sind Arrays, deren Größe Du während der Programmausführung festlegen kannst. Das geht mit statischen Arrays nicht: Bei statischen Arrays mußt Du die Größe schon bei der Programmierung des Programms festlegen.

Wenn Du Deinen Array mit

int feld[100];

anlegst, ist dieser Array grundsätzlich 100 Element groß. Aber was schreibst Du in die eckige Klammer, wenn Du beim Erstellen des Programms noch gar nicht weißt, wie groß Dein Array sein muß?

Beispiel:
Sagen wir mal, du möchtest ein Programm schreiben, das irgendwelche mathematischen Berechnungen anhand einer Zahlenfolge durchführt. Die Zahlen werden vom Benutzer eingegeben und in einem Array gespeichert. Bei Programmstart legt der Benutzer per Eingabe fest, wieviele Zahlen er eingeben möchte:

INT nAnzahl; // enthält die Anzahl der einzugebenden Zahlen
nAnzahl=Benutzereingabe(); // hier wird der Benutzer aufgefordert, die Anzahl der Zahlen festzulegen

Du weißt also erst nach dem Programmstart, wie groß Dein Array sein muß. Nun kannst Du Dir natürlich statisch einen sehr großen Array anlegen:

INT nZahlen[1000]; // Das wird schon reichen... mehr tippt eh' keiner ein. Hoffentlich jedenfalls

Damit hat Dein Programm zwei gravierende Nachteile:

  1. Wenn der Benutzer nur 10 Zahlen eingeben will, verschwendest Du Speicher
  2. Wenn der Benutzer nun doch mal mehr als 1000 Zahlen eingeben will, geht das nicht mit Deinem Programm

Nun ist die „Speicherverschwedung“ in diesem Beispiel noch ziemlich klein. Aber im Allgemeinen hat ein Programm eine Vielzahl von Arrays. Der reservierte, aber unbenutzte Speicher summiert sich also. Stell Dir z.B. ein Bildbetrachtungsprogramm vor: Der eine möchte auf seinem Billig-PC einfach nur kleine (wahrscheinlich nicht jugendfreie) Bilder mit 640x480 Pixel ansehen, die er im Internet gefunden hat. Der andere muß auf seinem HighEnd-PC große Bilder mit 6400x4800 Pixel laden. Wenn Du die statischen Arrays für den Bildspeicher nur für kleine Bilder dimensionierst, kann der zweite Benutzer seine Bilder nicht laden. Wenn das Programm aber für große Bilder ausgelegt ist, kann der erste Benutzer das Programm nicht starten, weil sein PC nicht über genügend Arbeitsspeicher verfügt.

Nun zurück zu dem Beispiel mit der Zahlenfolge:
Wenn Du statt des statischen Arrays einen dynamischen Array verwendest, entfallen die oben genannten Nachteile. Das sieht dann etwa so aus:

INT nAnzahl; // enthält die Anzahl der einzugebenden Zahlen
nAnzahl=Benutzereingabe(); // hier wird der Benutzer aufgefordert, die Anzahl der Zahlen festzulegen
// INT nZahlen[nAnzahl]; // das geht nicht...
INT \*pnZahlen=new INT[nAnzahl]; // ... aber das geht. Die Größe des Arrays hängt von der Benutzerabfrage ab

Jetzt solltest Du noch sicherstellen, daß der Speicher für den Array auch wirklich reserviert wurde:

if (pnZahlen==NULL) // Überprüfen, ob der Array wirklich erstellt wurde
 exit; // Fehler bei der Speicherreservierung, also Programm beenden

Ganz wichtig, wie Markus schon gesagt hat, ist, daß der reservierte Speicher auch wieder frei gegeben wird, nachdem er nicht mehr benötigt wird. Sonst gibt es Speicherlecks zur Laufzeit, und das sind wirklich unangenehme Fehler! Also Speicher wieder freigeben, z.B. beim Beenden des Programms:

delete [] pnZahlen;

Ich hoffe, das hilft Dir ein wenig weiter. Wenn Du noch Fragen hast, nur zu!

Gruß
Uwe