Speicher allokieren fuer Objekte [Geloest]

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Speicher allokieren fuer Objekte [Geloest]

Beitrag von heinz » 09.12.2020 21:47:43

Hallo Zusammen,

ich programmiere ab und zu "Dinge" fuer mich die ich gerade brauche.
Und wenn ich etwas mit Objekten mache (was sehr oft der Fall ist) dann mach ich das meist so: (Pseudo-Code aus dem Kopf...)

Code: Alles auswählen

class objeKt
{
 public:
  void Mach_was();
 private:
  int iregendwas;
};

int objektmenge=0;
objeKt** objektliste = NULL;

void Neues_objekt()
{
 objektmenge++;
 objektliste = (objeKt**) realloc(objektliste , objektmenge * sizeof(objeKt*));
 objektliste[objektmenge-1] = new objeKt();
}

for(int o=0;o<objektmenge;o++)
{
 delete(objektliste[o]);
}
free(objektliste);
Das funktioniert wunderbar in sehr vielen meier Projekte.

Allerdings lese ich immer wieder, "Man soll malloc, calloc, realloc und free nicht mit new und delete verwenden."

Warum nicht?
Und wie soll man es sonst machen, wenn vorher nicht bekannt ist wieviele Objekte es mal werden?
Mit new kann ich mir zwar Speicher allokieren aber danach die Groesse nicht mehr aendern.

Wie macht man es denn "richtig"?
Bzw. Was ist an "meinem" Code so falsch/gefaehrlich/unzureichend wasauchimmer...

Gruss,
heinz
Zuletzt geändert von heinz am 10.12.2020 14:37:56, insgesamt 1-mal geändert.

Benutzeravatar
MSfree
Beiträge: 11604
Registriert: 25.09.2007 19:59:30

Re: Speicher allokieren fuer Objekte

Beitrag von MSfree » 09.12.2020 22:00:08

heinz hat geschrieben: ↑ zum Beitrag ↑
09.12.2020 21:47:43
Allerdings lese ich immer wieder, "Man soll malloc, calloc, realloc und free nicht mit new und delete verwenden."
Grundsätzlich sollte man in C++ gar kein malloc/calloc und free verwenden.

Ausserdem kann man in C++ die new und delete Operatoren überschreiben. Delete führt ausserdem den Destruktor der jeweiligen Klasse aus. Objekte, die man mit (m|c)alloc anlegt und mit delete freigibt, könnten im Destruktor landen, was dann in einem Segmentationfault enden kann.

Ich würde dir aber vorschalgen, dir man die STL reinzuziehen. std::vector ist eine praktische Templateklasse, bei der du dir um Speicher anfordern und Freigabe gar keine Gedanken mehr zu machen brauchst.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Speicher allokieren fuer Objekte

Beitrag von heinz » 10.12.2020 13:30:25

Hallo MSfree,

erstmal Danke fuer Deine Antwort.

Ich hab mal ein wenig im Netz gesucht und ein paar Beschreibungen ueber vector gelesen.
Dann hab ich versucht das Gelesene umzusetzen und habe prompt ein Problem.

Hier ist mein Testcode:
NoPaste-Eintrag41220

Und hier die Ausgabe die er erzeugt:

Code: Alles auswählen

---------------------------------------- Objekte erstellen
Objekt 0 erzeugt.
Objekt 0 vernichtet.
Objekt 0 macht was...
 Objektmenge= 1
Objekt 1 erzeugt.
Objekt 0 vernichtet.
Objekt 1 vernichtet.
Objekt 1 macht was...
 Objektmenge= 2
Objekt 2 erzeugt.
Objekt 0 vernichtet.
Objekt 1 vernichtet.
Objekt 2 vernichtet.
Objekt 2 macht was...
 Objektmenge= 3
Objekt 3 erzeugt.
Objekt 3 vernichtet.
Objekt 3 macht was...
 Objektmenge= 4
Objekt 4 erzeugt.
Objekt 0 vernichtet.
Objekt 1 vernichtet.
Objekt 2 vernichtet.
Objekt 3 vernichtet.
Objekt 4 vernichtet.
Objekt 4 macht was...
 Objektmenge= 5
----------------------------------- Objekte was tun lassen
Objekt 0 macht was...
Objekt 1 macht was...
Objekt 2 macht was...
Objekt 3 macht was...
Objekt 4 macht was...
--------------------------------------- Objekte vernichten
Objekt 0 vernichtet.
Objekt 1 vernichtet.
Objekt 2 vernichtet.
Objekt 3 vernichtet.
Objekt 4 vernichtet.

Warum wird beim Erzeugen der Objekte immer der Destructor aufgerufen?
Und warum werden immer die Destructoren aller anderen Objekte ebenfalls aufgerufen? (Ausser bei Objekt 3???)

Warum kann ich die Zeilen 50 und 51 einfach austauschen ohne eine Veraenderung festzustellen?

Was mach ich falsch, wo liegen meine Denkfehler?

Gruss,
heinz

Benutzeravatar
MSfree
Beiträge: 11604
Registriert: 25.09.2007 19:59:30

Re: Speicher allokieren fuer Objekte

Beitrag von MSfree » 10.12.2020 14:01:16

Code: Alles auswählen

for(int o=0;o<5;o++)
{
       objektliste.push_back(o);
//     objektliste.push_back(objeKt(o)); // Warum geht das auch?
       objektliste[o].Machwas();
       printf(" Objektmenge= %li\n",objektliste.size());
}

Code: Alles auswählen

objektliste.push_back(o);
erwartet als Argument für push_back ja eigentlich ein Objekt der Klasse objeKt. Du fütterst es aber mit dem int "o". Also wird ein temporäres Objekt erzeugt, dann gepusht und anschließend wird das temporäre Objekt wieder zerstört.

Code: Alles auswählen

objektliste.push_back(objeKt(o)); 
Hier erzeugst du das Objekt objeKt explizit als Übergabeparameter.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Speicher allokieren fuer Objekte

Beitrag von heinz » 10.12.2020 14:06:58

Hallo nochmal,

ich glaube, ich hab es hinbekommen:

Code: Alles auswählen

int main()
{
printf("---------------------------------------- Objekte erstellen\n");

	std::vector<objeKt*> objektliste;


	for(int o=0;o<5;o++)
	{
		objeKt* ob=new objeKt(o);
		objektliste.push_back(ob);
		objektliste[o]->Machwas();
		printf(" Objektmenge= %li\n",objektliste.size());
	}

printf("----------------------------------- Objekte was tun lassen\n");

	for(int o=0;o<5;o++)
	{
		objektliste.at(o)->Machwas();
	}

printf("--------------------------------------- Objekte vernichten\n");

	objektliste.clear();
}

Das erzeugt eine Ausgabe wie sie sein soll.

Ich verstehe es so:
Der vector "objektliste" enthaelt eine Liste (Array) von Pointern auf Objekte im Speicher.
Und das bedeutet auch, delete nicht zu verwenden sondern z.B. objektliste.pop_back(); und somit das loeschen der Objekte dem vector zu ueberlassen.

Ist das so korrekt?

Gruss,
heinz

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Speicher allokieren fuer Objekte

Beitrag von heinz » 10.12.2020 14:13:02

Nochmal Danke fuer Deine Hilfe.
MSfree hat geschrieben: ↑ zum Beitrag ↑
10.12.2020 14:01:16
Also wird ein temporäres Objekt erzeugt,
Wenn die Objekte nur temporaer waren, warum konnte ich dann spaeter die Methode "objektliste[o].Machwas();" aufrufen? (Und beim ".clear();" auch die Destructoren...)

Benutzeravatar
MSfree
Beiträge: 11604
Registriert: 25.09.2007 19:59:30

Re: Speicher allokieren fuer Objekte

Beitrag von MSfree » 10.12.2020 14:26:07

heinz hat geschrieben: ↑ zum Beitrag ↑
10.12.2020 14:13:02
Wenn die Objekte nur temporaer waren, ...
Das temporäre Objekt ist nur das, welches sich in der Parameterliste von push_back befindet. Im std::vector wird dieses temporäre Objekt per Copy-Contructor in den Vektor eingefügt.

Benutzeravatar
heinz
Beiträge: 535
Registriert: 20.12.2007 01:43:49

Re: Speicher allokieren fuer Objekte

Beitrag von heinz » 10.12.2020 14:37:22

Alles klar.

Ich Denke/Hoffe/Glaube ich habs jetzt verstanden. :wink:

Vielen Dank fuer Deine Zeit.

Gruss,
heinz

Antworten