delete bei void*
-
Hi,
ich hab mal ne frage zum delete Operator. Folgendes:
int *ptr = new int; delete ptr; //ist ja das gleiche wie int *ptr = (int *)malloc(sizeof(*ptr)); free(ptr);Ich habe mal gehört dass free() einen void* freigeben kann, delete aber nicht. Stimmt das? Beispiel:
void func(void *ptr) { delete ptr; } int *ptr = new int; func(ptr);Würde das jetzt den Speicher auch wieder freigeben?
Achja, wenn man mit new ein array anfordert, also z.B. new int[20] muss man ja delete[] nehmen um den Speicher freizugeben.
Wie ist das wenn man new int[1] macht. Gibt delete[] dann zu viel Speicher frei?^^mfg
-
Das Hintergrund ist dass new den Konstruktor und delete den Destruktor aufrufen, malloc/free machen das nicht.
Außerdem kannst du davon ausgehen dass beide ganz andere Speicherlisten verwalten, dh. sie sind nicht kompatibel.Achja, wenn man mit new ein array anfordert, also z.B. new int[20] muss man ja delete[] nehmen um den Speicher freizugeben.
Wie ist das wenn man new int[1] macht. Gibt delete[] dann zu viel Speicher frei?^^Nö.
-
new/delete und new[]/delete[] und malloc/free dürfen drei völlig unterschiedliche Speicherbereiche benutzen. Als Anwender darfste nie einen Zeiger freigeben, der von einer anderen Sorte angelegt wurde.
Hast Du den void*, den Du mit delete gerne freigeben würdest, denn überhaupt mit new geholt?
-
und wie is das jetzt mit dem void *? heißt das, dass das system sozusagen speichert an welcher adresse wie viel speichert angefordert is, egal was für einen typ der zeiger hat?
-
volkard schrieb:
new/delete und new[]/delete[] und malloc/free dürfen drei völlig unterschiedliche Speicherbereiche benutzen. Als Anwender darfste nie einen Zeiger freigeben, der von einer anderen Sorte angelegt wurde.
Hast Du den void*, den Du mit delete gerne freigeben würdest, denn überhaupt mit new geholt?
naja in dem beispiel ja schon
void func(void *ptr) { delete ptr; } int *ptr = new int; func(ptr);
-
Das ist undefiniertes Verhalten.
Einziger Fall, wo angeforderter Zeigertyp (von
newzurückgegeben) und freizugebender Zeigertyp (andeleteübergeben) verschieden sein dürfen, sind Derived-To-Base-Konvertierungen mit virtuellem Destruktor in der Basisklasse.
-
Naja, Du hast Dir eigentlich einen int* geholt.
Hast nichtvoid *ptr = new void;geschrieben.
-
new void? Gehe mal davon aus dass du jetzt vom prinzip sprichst weil new void klappt ja nicht.^^
Naja jedenfalls hat ja free() als parameter auch nen void*. D.h. da müsste der typ egal sein oder wie is das?
-
Du musst zwischen C++ und C unterscheiden.
In C hatte man keine andere Möglichkeit, weshalb dort die Verwendung von void * keine Probleme bereitet.
In C++ haut das nicht mehr hin, da Klassen weitaus komplexer sind. Der Typ muss daher immer feststehen, damit du delete bzw. delete[] aufrufen kannst.
Im übrigen ist es gar nicht gut, wenn man new und malloc, etc. im Programm mischt. Entscheide dich für C oder C++.
-
d.h. delete bei einem void * gibt keinen speicher oder eben die falsche anzahl frei?
-
Was delete dann macht ist undefiniert. Vielleicht gibt es den Speicher frei, vielleicht geht auch die Welt unter. Man kann sich nicht darauf verlassen und sollte es daher unterlassen.
-
1700 schrieb:
new void? Gehe mal davon aus dass du jetzt vom prinzip sprichst weil new void klappt ja nicht.^^
Sehe ich auch so. Und deswegen muß delete auch keinen void* nehmen.
1700 schrieb:
Naja jedenfalls hat ja free() als parameter auch nen void*. D.h. da müsste der typ egal sein oder wie is das?
Insofern ja, als daß Du vom malloc auch einen void* bekommen hast und ungetypten Speicher angelegt hast. Ohne Konstruktoraufruf. Und free machts dann auch ohne Destruktoraufruf.
-
gut alles klar... denke es ist alles gesagt...
danke jungs
-
Unbekanntes Objekt freigeben geht mit Templates.