Was wird davon alles freigegeben
-
Ich hab mal ein paar Szenarien zur Speicherverwaltung und da ich die Funktionsweise teilweise sehr widersprüchlich lese wollte ich mal wissen welche der folgenden Szenarien alles löschen und welche Speicherlecks hinterlassen:
a)
char* a = (char*) calloc(10, sizeof(1));
free(a);
b)
char* a = (char*) malloc(sizeof(int));
free(a);
c)
int* a = (int*)malloc(sizeof(char));
free(a);
d)
int* a = new char(3);
delete a;
e)
class A
{
int a, b, c;
};
class B : public A
{
int d, e;
};
[...]
A* a = (A*)new B();
delete a;Wär ganz nett wenn mir jemand sagen könnte welche Lecks hinterlassen und vor allem warum.
-
a-d hinterlassen keine Leaks. e erzeugt undefiniertes Verhalten, weil A keinen virtuellen Destruktor hat. Wenn es compilieren würde, weil B auch keinen public Konstruktor hat

edit: tja, d compiliert auch nicht, aber würde, wenn, kein Leak hinterlassen.
-
mhm, bei d fehlt ein Typecast, aber gut.
Also ist die Größe des reservierten Speichers unwichtig und nur die Destruktoren zählen? Wird bei Fall b oder dessen new/delete Äquivalent auch wirklich nicht nur 1 Byte gelöscht?
wie siehts damit aus?
class A
{
int a, b, c;
public:
virtual ~A(void){}
};
class B : public A
{
int d, e;
public:
~B(void){}
};
[...]
A* a = (A*)new B();
delete a;
-
Ankou schrieb:
mhm, bei d fehlt ein Typecast, aber gut.
nanu? d ist korrekt einfach als
int* d = new intAlso ist die Größe des reservierten Speichers unwichtig und nur die Destruktoren zählen?
es ist wohl etwas unklar, welche antwort du dir erwartest. die größe des reservierten speichers ist nur als unterscheidung zwischen der allokation einzelner objekte und arrays wichtig. im einen fall nimmst du new/delete und im anderen new[]/delete[]. auf die größe kommt es aber direkt tatsächlich nicht an.
wie siehts damit aus?
class A
{
int a, b, c;
public:
virtual ~A(void){}
};
class B : public A
{
int d, e;
public:
~B(void){}
};
[...]
A* a = (A*)new B();
delete a;kein speicherleck, alles gelöscht, was gelöscht werden soll. /edit: allerdings wird die konvertierung von B nach A automatisch übernommen. solche (C-style) casts solltest du in C++ allerdings sowieso nicht verwenden. entweder static_cast oder - in diesem fall - gar keinen:
A* a = new B;
-
Bashar schrieb:
a-d hinterlassen keine Leaks. e erzeugt undefiniertes Verhalten, weil A keinen virtuellen Destruktor hat. Wenn es compilieren würde, weil B auch keinen public Konstruktor hat

Klar hat B einen public Ctor - du siehst ihn nur nicht
(der Compiler spendiert jeder Klasse einen impliziten Default-Ctor, Copy-Ctor, op= und Dtor, die alle public gesetzt sind (den Default-Ctor nur, wenn du keinen benutzerdefinierten hast))@Ankou: Variante (c) compiliert zwar, dürfte dir aber Probleme bereiten, wenn du etwas mit dem Speicher machen willst:
int* a = (int*)malloc(sizeof(char)); *a = 4711;//BUMM free(a);
-
ok danke.
Btw, steht im Default Konstruktor mehr drin als wenn ich einen mit {} erstelle?
@queerboy:
da stand schon absichtlich new char. Das is das selbe wie c) nur im new/delete Paket. Aber wenn c geht, wird wohl auch d gehen, oder?
-
Ankou schrieb:
ok danke.
Btw, steht im Default Konstruktor mehr drin als wenn ich einen mit {} erstelle?nein.
@queerboy:
da stand schon absichtlich new char. Das is das selbe wie c) nur im new/delete Paket. Aber wenn c geht, wird wohl auch d gehen, oder?nein, tut es nicht - bei Variante c hast du noch einen Cast drin, bei Variante d nicht (und char* und int* sind nicht miteinander kompatibel). Und selbst mit einem Cast hättest du da effektiv das selbe Problem wie bei Variante c - BUMM!
-
Dass ich in den Pointer möglichst nichts schreiben sollte is mir schon klar^^
War ja auch rein theoretisch...
und zu dem Typecast:Ankou schrieb:
mhm, bei d fehlt ein Typecast, aber gut.nanu? d ist korrekt einfach als int* d = new int
Deswegen hab ich das gesagt. Dass da ein Typecast fehlt hab ich ja gesagt

-
also dir geht es nur darum, zu wissen, ob delete genausoviel speicher freigibt, wie mit new angefordert wurde? dann ja. dito bei *alloc & free. bei new und delete musst du dann nur bei den jeweiligen versionen für arrays aufpassen.