C++ Speicher allkokieren, Konstruktor, Destruktor

WallaceXIV

PCGH-Community-Veteran(in)
Ich hab mir was zusammen programmiert, aber ich habe jetzt ein Problem damit, ich blick nicht genau durch was ich da eigentlich mache.

Ich lese eine Textdatei mit mehreren Zeilen und verschiedenen Werten ein.

Am Anfang der Testdatei habe ich die Anzahl der Zeilen bzw. Datensätze gespeichert.

textdatei-jpg.428162


Nach dieser Zahl richtet sich die Größe des allokierten Speichers

Code:
class Klasse 1
{
    private:
           ....

    public:
           Klasse1() {} // Konstruktor
           ....

};  // Ende Klasse1


class Klasse2
{
    private:
            int Anzahl;
    public:
            Klasse1 *Test; // inititalisiert Konstruktor der Klasse1 mit dynamischen Werten
            Klasse2() {DatenEinlesen();} // Konstruktor
            ~Klasse2() {delete[] Test;} // Destruktor
            void DatenEinlesen();
            

};  // Ende Klasse2

void Klasse2::DatenEinlesen()
{
   .....
   ifstream lesen("blabla.txt");
   lesen >> Anzahl;
   Test = new Klasse1[Anzahl];
   
   for (int i = 0; i < Anzahl; i++)
   {
      ....
      ....
      ....
   }

   lesen.close();
}
Jetzt will ich einen neuen Datensatz hinzufügen, aber der Speicher wurde ja schon allokiert. Neu allokieren bringt einen Fehler, genau so wie ohne neu allokieren und einfach so hinzufügen.

Wie funktioniert das genau?
 

Anhänge

  • textdatei.JPG
    textdatei.JPG
    19,6 KB · Aufrufe: 387
Zuletzt bearbeitet:
Also ich verstehe dich gerade nicht komplett.
Also so wie ich das sehe, versuchst du in Klasse 2 ein Array von Objekten der Klasse 1 zu speichern? Klasse 1 enthält dann Daten, die in der Datei stehen (Name, etc..).

Wenn dem so ist, guck dir mal Stl Container an an. STL Containers - C++ Reference
Das sind alle Container, wichtig für dich sind vector und list. Also ich verplane immer wieder wofür was war, bei einem konnte man keine Datensätze in der Mitte einfügen, sondern nur am Anfang oder Ende.

Jedenfalls kann man dann immer Datensätze hinzufügen.
Beispiel:
Code:
   ifstream lesen("blabla.txt");
   lesen >> Anzahl;
   std::vector<Klasse1> Test;
   for(blabla)
   {
       Klasse1 tmp = new Klasse1(KonstruktorZeug);
       Test.push_back(tmp);

So müsste das dann aussehen. Ich hoffe ich hab das Problem verstanden..

mfg
Lukas
 
Also ich initialisiere den Konstruktor der Klasse1 mit den eingelesenen Daten aus der Textdatei. Ich verstehe es aber selbst nicht zu 100%. Das gab es so auf irgendeiner Internetseite, ich habe es halt auf meine Bedürfnisse angepasst. Es funktioniert auch soweit, nur das anfügen von Daten bzw. dann später das löschen (noch nicht versucht) funktioniert nicht.
 
Das Anfügen von Daten ist in deinen Konstrukt immer, erzeugen eines neuen Arrays mit n+x Objekten (n sind die Bestandsdatensätze und x die Anzahl an neuen Datensätzen), dann kopierst du den Inhalt des alten an den Anfang des neuen Arrays und die neuen dadrüber. Soweit klar?

Hast du dich schonmal mit dynamischen Datenstrukturen beschäftigt? Das ist genau das was du hier bräuchtest. ;)
 
Ja hab mich damit schon beschäftigt. In C ist das auch kein größeres Problem, nur mit C++ tu ich mich da schwer. Mir liegt die objektorientierte Denkweise nicht so. ;)

Soll ich neuen Speicher allkokieren? Also quasi temporär zwischenspeichern und dann das Original-Feld überschreiben?
 
Ja hab mich damit schon beschäftigt. In C ist das auch kein größeres Problem, nur mit C++ tu ich mich da schwer. Mir liegt die objektorientierte Denkweise nicht so. ;)

Soll ich neuen Speicher allkokieren? Also quasi temporär zwischenspeichern und dann das Original-Feld überschreiben?

Du kannst im Prinzip in C++ genauso arbeiten wie bei C! Nur wenn virtuelle Funktionen im spiel sind, dann wäre etwas zu beachten. Also wenn du das ganze schon mal in C gemacht hast, dann einfach übertragen.

Was musst du machen? Wie gesagt im Endeffekt ist das recht einfach. Du musst ein neues Array erzeugen, das umsoviel größer ist wie du neue Elemente hast. Nemmen wir an du hast eine Array mit n Elemente und willst x Elemente hinzufügen, dann ist die neue Größe n+x.

newArray = new Type[n+x];

Dann kopierst du den Inhalt des alten in das neue Array (einfache for-schleife oder memcpy), und ab n kommen dann die neuen Elemente (auch wieder einfach per for schleife oder memcpy). soweit verstanden?
 
Jo hab ich verstanden, Danke. Ich probiere es morgen aus und gebe Bescheid. Der nächste Schritt ist dann noch löschen eines Datensatzes, da muss ich mit noch was überlegen wenn zwischen drin was gelöscht wird.
 
wenn schon memcpy, geht schneller ;)
Aber mal ne frage: warum wird hier kein dynamisches Array benutzt? Also list oder vector, wie ich schon vorgeschlagen habe..
 
Das Array ist doch dynamisch. Es wird doch erst zur Laufzeit angelegt.

Code:
Test = new Klasse1[Anzahl];
 
Er meint eigentlich eine dyn. Datenstruktur, zum Beispiel ne Liste. Da kannst du dann einfach Elemente hinzufügen und wieder entfernen, ohne dich um den eigentlichen Speicher zu kümmern.
 
Das Array ist doch dynamisch. Es wird doch erst zur Laufzeit angelegt.
Also nur zur Info für dich, wenn du ein Array mit der größe n erzeugst, dann ist dieser auch nur so große das es Platz für n Elemente hat. ->n*memsize...

Ergo ist da hinter etwas irgendetwas anderes und wenn du das überschreibst, dann beginnt der Spaß erst richtig! :daumen:

Er meint eigentlich eine dyn. Datenstruktur, zum Beispiel ne Liste. Da kannst du dann einfach Elemente hinzufügen und wieder entfernen, ohne dich um den eigentlichen Speicher zu kümmern.
Naja, auch ein dynamischer Array (und um was anderes geht es hier ja auch nicht) ist eine dynamische Datenstruktur. ;) Sie hat zwar nicht die Vorteile beim hinzufügen/entfernen wie eine Liste, dafür aber schnellen Element Zugriff.

Das wäre zu viel Aufwand für das kleine Programm. Es soll am Ende nur funktionieren.
Was soll ich hier drauf noch antworten? Wir reden hier, ohne Prüfung, im besten Fall von einen vier Zeiler! Im wahrsten Sinne des Wortes! Sorry, aber wenn dir das zu viel ist, dann tut es mir leid!
 
Naja, auch ein dynamischer Array (und um was anderes geht es hier ja auch nicht) ist eine dynamische Datenstruktur. ;) Sie hat zwar nicht die Vorteile beim hinzufügen/entfernen wie eine Liste, dafür aber schnellen Element Zugriff.
Ja, ich hatte als alter Java-Programmierer auch ne ArrayList (also keine verkettete Liste) im Kopf ;)
 
Nun ja, dann solltest du ja jetzt wissen was du zu machen hast. Diese Handvoll Zeilen sollten ansich kein Problem sein und es ist ein schöner Lerneffekt. ;)

Ich probiers dann gleich aus. Danke.

EDIT: Ein Problem ist noch, ich habe die Daten ja alle in den Konstruktor geladen. Den Konstruktor müsste ich ja jetzt wieder nehmen um den temporären Speicher zu allokieren. Der Zeiger muss doch vom Typ des Konstruktors sein oder nicht?


Code:
...

Klasse1() {} // Konstruktor

...

Klasse1 *Test; // inititalisiert Konstruktor der Klasse1 mit dynamischen Werten

...

Test = new Klasse1[Anzahl];
 
Zuletzt bearbeitet:
Ihr seid Hammer Leute :D
Ja, Java is doof
Ja, es ist kaum Arbeit. Listen sind einfach total einfach zu nutzen (nur Schleifendurchläufe brauchen ein wenig Einarbeitungszeit;) )

Tipp: Nimm jetzt verdammt nochmal std::list !! oder vector, wenn du bock hast.
Es lößt einfach alle deinen Array Probleme. Arrays nimmt man nur wenn man extrem performance orientiert ist, wenn man den ganzen Programmablauf über die Größe des Arrays nich änder oder wenn man alternativen noch nicht kennt :P

viel glück noch bei deinem teil
 
Ihr seid Hammer Leute :D
Ja, Java is doof
Ja, es ist kaum Arbeit. Listen sind einfach total einfach zu nutzen (nur Schleifendurchläufe brauchen ein wenig Einarbeitungszeit;) )

Tipp: Nimm jetzt verdammt nochmal std::list !! oder vector, wenn du bock hast.
Es lößt einfach alle deinen Array Probleme. Arrays nimmt man nur wenn man extrem performance orientiert ist, wenn man den ganzen Programmablauf über die Größe des Arrays nich änder oder wenn man alternativen noch nicht kennt :P

viel glück noch bei deinem teil

Nicht so aggro. :D
 
Zurück