delete [] p ?
-
Ich hab ein Stück Code, der für mich keinen Sinn ergibt.
Es wird dynamisch einer Variablen *p ein Objekt mit new zugewiesen und mit
p->methode(); genutzt.Aber warum steht am ende delete[] p?
Ich mein klar, mit new erzeugte Objekte auf dem Heap müssen mit delete gelöscht werden, aber warum ist der Array Operator dort mitbei?
Bedeutet dies, dass alle zugehörigen Reservierungen freigegeben werden? Und wenn ja, was wird dann mit delete p ohne die [] gelöscht? Doch der Speicher, der von dem Objekt reserviert wurde, nicht wahr?
-
Seikilos schrieb:
...
Aber warum steht am ende delete[] p?
Ich mein klar, mit new erzeugte Objekte auf dem Heap müssen mit delete gelöscht werden, aber warum ist der Array Operator dort mitbei? ......weil er beim new[] auch dabei ist.

Merke:
new -> delete new[] -> delete[]Alles Andere ist undefiniert.
Sagen wir mal andersherum: Wenn das hier stimmt:
Seikilos schrieb:
...Es wird dynamisch einer Variablen *p ein Objekt mit new zugewiesen ...
... dann ist das [] beim delete falsch.
Gruß,
Simon2.
-
In meinem Code, den ich bekommen habe, ist dort kein [].
-
Seikilos schrieb:
In meinem Code, den ich bekommen habe, ist dort kein [].
Lass mal sehen.
Wiue gesagt: Kann falsch sein ... kann aber auch sein, dass Du es übersiehst weil da sowas steht:... new char [b][[/b]100[b]][/b];Gruß,
Simon2.
-
Es wird ja kein Array, sondern ein Objekt erzeugt
Person *p2 = new Person(name2, age); p2->print(); delete [] p2;Es wird danach explizit gefragt, was delete [] p2; bedeutet.
Ich weiß nicht, ob da irgendwo ein Schreibfehler sein soll, aber wenn danach gefragt wird?
-
ich frage mich, was die unterscheidung zwischen delete und delete[] überhaupt soll? steckt da ein tieferer sinn dahinter?
-
Ich glaub das ist ja eben meine Frage hier

-
Ehm würde mich mal interessieren was passiert wenn du folgendes machst:
char* arr_ptr = new char[128]; arr_ptr[127] = 0; delete arr_ptr; delete [] arr_ptr;ich würde glaube ich erwarten dass er folgendes macht(hab aber noch nicht wirklich drüber nachgedacht:
delete &arr_ptr[0]; delete [] arr_ptr; // BUMM! ;)also praktisch das 1. Element des Arrays löscht.
Person* ptr = new Person(name, age); ptr->print(); delete ptr;... sieht nach dem Tippfehler aus ...
-
Ja aber drunter steht noch
Zweimal Tippfehler?
-
Oder einfach ein Denkfehler. Auf jeden Fall müssen mit "new" erzeugte Objekte mit "delete" freigegeben werden, frei von irgendwelchen eckigen Klammern.
Achso, und was das soll: delete bzw delete[] gibt nicht nur Speicher frei, sondern ruft ja auch den/die Destruktor/en auf. Bei delete[] weiß der Compiler halt, dass er von jedem Objekt den Destruktor aufrufen soll, nicht nur vom ersten. Und danach erst wird der Speicher freigegeben.
-
Hmm es ist nicht definiert. DU solltest das Buch wechseln

<a href= schrieb:
IBM">The result of deleting an array object with delete is undefined, as is deleting an individual object with delete[]. The array dimensions do not need to be specified with delete[].
-
Ich sollte eher den Professor wechseln, denk ich

-
Badestrand schrieb:
Bei delete[] weiß der Compiler halt, dass er von jedem Objekt den Destruktor aufrufen soll, nicht nur vom ersten.
aber wenn delete auf ein mit new[] erzeugtes array sowieso undefiniert ist, warum muss man denn dann explizit delete[] aufrufen?
wenn der compiler bei delete[] weiß, wieviele felder freizugeben sind, müsste er es doch auch bei delete wissen können.
-
[][][] schrieb:
aber wenn delete auf ein mit new[] erzeugtes array sowieso undefiniert ist, warum muss man denn dann explizit delete[] aufrufen?
Weil der Compiler das an gewissen Stellen ja gar nicht wissen kann, ob der übergebene Zeiger auf ein Array zeigt oder auf ein einzelnes Objekt:
void MyPersonalDeleteFunction( int* p ) { delete p; // oder delete[] p; // ? } .. int* a = new int; int* b = new int[100]; MyPersonalDeleteFunction( a ); MyPersonalDeleteFunction( b );[][][] schrieb:
wenn der compiler bei delete[] weiß, wieviele felder freizugeben sind, müsste er es doch auch bei delete wissen können.
Da ist was wahres dran.. Allerdings wissen die Compiler oft mehr, als was der Standard vorgibt zu wissen.
-
Nun, er kompiliert und meckert nicht, wenn er hier ist...
Person *p2 = new Person(name2, age); p2->print(); delete [] p2;
-
Seikilos schrieb:
Nun, er kompiliert und meckert nicht, wenn er hier ist...
Das muss er auch nicht. Er könnte auch einen Sack Reis in Korea sprengen. Es ist und bleibt aber undefiniert, sprich illegal.
-
Ich freu mich schon drauf, dem Lehrer auf die Frage antworten zu können, dass das ein Fehler ist...

-
[][][] schrieb:
wenn der compiler bei delete[] weiß, wieviele felder freizugeben sind, müsste er es doch auch bei delete wissen können.
Die Verwaltung der Arraylänge kostet zusätzlichen Aufwand, den kann sich der Compiler sparen, wenn er "weiß", daß er mit Einzelobjekten hantiert.
Eine Beispiel-Implementierung (Semi-Pseudocode):
//op new - liefert Speicher für ein Objekt (size Bytes) void* operator new(size_t size) { return malloc(size); } void operator delete(void* p) { free(p); } //op new[] - liefert Speicher für ein Array (size Bytes gesamt) void* operator new[](size_t size) { char* ptr = malloc(size+sizeof(size_t)); *((int*)ptr) = size; return ptr+sizeof(size_t); } void operator delete[](void*p) { free((char*)p-sizeof(size_t)); }
-
CStoll schrieb:
Die Verwaltung der Arraylänge kostet zusätzlichen Aufwand, den kann sich der Compiler sparen, wenn er "weiß", daß er mit Einzelobjekten hantiert.
dein beispiel zeigt aber, wie gering der zusätzliche aufwand wäre - im vergleich zu dem gewinn an konsistenz und dem verschwinden einer bösen potenziellen fehlerquelle, wenn delete[] wegfiele.
Badestrand schrieb:
Weil der Compiler das an gewissen Stellen ja gar nicht wissen kann, ob der übergebene Zeiger auf ein Array zeigt oder auf ein einzelnes Objekt:
wenn er über die größe des speicherbereichs buch führen kann, könnte er doch genauso gut auch über die objektanzahl buch führen?
-
[][][] schrieb:
wenn er über die größe des speicherbereichs buch führen kann, könnte er doch genauso gut auch über die objektanzahl buch führen?
Der, der über die Größe des Speichers Buch führt, ist aber möglicherweise (bzw. meistens) jemand anderes, als derjenige, der sich um die Destruktion kümmert. Wenn z.B. die Operatoren new und delete auf malloc und free zurückgreifen, ist ihnen die Größe des Speichers egal, darum kümmern sich malloc/free. Die Destruktion von Objekten muss der C++-Teil übernehmen, dafür ist aber nur die Anzahl erforderlich. (Wenngleich man natürlich zwischen Anzahl und Größe umrechnen kann).
-
[][][] schrieb:
CStoll schrieb:
Die Verwaltung der Arraylänge kostet zusätzlichen Aufwand, den kann sich der Compiler sparen, wenn er "weiß", daß er mit Einzelobjekten hantiert.
dein beispiel zeigt aber, wie gering der zusätzliche aufwand wäre - im vergleich zu dem gewinn an konsistenz und dem verschwinden einer bösen potenziellen fehlerquelle, wenn delete[] wegfiele.
Es gibt verschiedene Möglichkeiten, die Größe des Arrays zu verwalten (u.a. auch über eine map<void*,size_t> oder per Zugriff auf die Verwaltungsdaten von malloc/free) - die jeweils ihre eigenen Vor- und Nachteile haben. Auf jeden Fall muß new[] diese Anzahl irgendwo hinterlegen und das kostet Platz* (und Rechenzeit).
* Bei kleinen Objekten kann es durchaus vorkommen, daß du damit deinen speicherbedarf verdoppelst.