VC++: Mit unbekannten Datenmengen umgehen

Hallo zusammen!

Ich bastel gerade an einem Programm, das Daten unbekannten Umfanges verarbeiten soll.
Stellen wir uns mal vor, es wäre eine Art Textverarbeitung. Ich will für jeden Absatz ein Objekt anlegen. Der Text besteht dann aus n Absätzen und einigen Grunddaten (Titel, Verfasser, Datum etc.). Ist n festm gibts kein Problem, ich definiere ein Array mit n Strings als Member von CText.
Das heißt, hier gehts ja schon los: Ich weiß ja nicht, wie lang die einzelnen Abschnitte sind.
Vor allem weiß ich aber nicht, aus wievielen Abschnitten mein Text besteht.
Wenn ich bei der Definition großzügig dimensioniere, verbrate ich jede Menge Speicher, den ich nie ausschöpfe.
Die einzige Lösung, die mir einfällt, ist, in CText ein Array von Zeigern auf die Abschnitte anzulegen.
Ist es sinnvoll, in diesem Fall jedem Abschnitt noch die Information zu geben, zu welchem TExt er gehört? Es soll allerdings immer nur ein Text geöffnet sein.
Außerdem soll das Ganze ja noch gespeichert werden. Gibt es da Schwierigkeiten? Dass das mit Serialize geht, weiß ich, aber wie, muss ich mir noch ansehen.

Macht man das wirklich so? Scheint mir doch recht unpraktisch. Oder sollte ich doch lieber eine Datenbank anlegen? Dann müsste ich mir das auch noch anlesen …

Gruß
Arndt

Hallo Arndt,

Ich bastel gerade an einem Programm, das Daten unbekannten
Umfanges verarbeiten soll.
Stellen wir uns mal vor, es wäre eine Art Textverarbeitung.
Ich will für jeden Absatz ein Objekt anlegen. Der Text besteht
dann aus n Absätzen und einigen Grunddaten (Titel, Verfasser,
Datum etc.). Ist n festm gibts kein Problem, ich definiere ein
Array mit n Strings als Member von CText.
Das heißt, hier gehts ja schon los: Ich weiß ja nicht, wie
lang die einzelnen Abschnitte sind.
Vor allem weiß ich aber nicht, aus wievielen Abschnitten mein
Text besteht.
Wenn ich bei der Definition großzügig dimensioniere, verbrate
ich jede Menge Speicher, den ich nie ausschöpfe.
Die einzige Lösung, die mir einfällt, ist, in CText ein Array
von Zeigern auf die Abschnitte anzulegen.
Ist es sinnvoll, in diesem Fall jedem Abschnitt noch die
Information zu geben, zu welchem TExt er gehört? Es soll
allerdings immer nur ein Text geöffnet sein.
Außerdem soll das Ganze ja noch gespeichert werden. Gibt es da
Schwierigkeiten? Dass das mit Serialize geht, weiß ich, aber
wie, muss ich mir noch ansehen.

Macht man das wirklich so? Scheint mir doch recht unpraktisch.
Oder sollte ich doch lieber eine Datenbank anlegen? Dann
müsste ich mir das auch noch anlesen …

Eine verkettete Liste wäre da wohl angebracht. Zudem solltest du dich noch mit der dynamischen Speicherverwaltung etwas auseinandersetzten.
Funktionen: malloc(), realloc() und free().

typedef struct Absch
{
 struct Absch \*voriger; // Zeiger auf vorigen sAbschnitt
 struct Absch \*naechster; // Zeiger auf nächsten sAbschnitt
 char text[];
} sAbschnitt;

sAbschnitt Anfang = {NULL, NULL, '\0'};

sAbschnitt \*neu(char \*txt)
{
 sAbschnitt \*ptr;
 int laenge;

 laenge = strlen(txt);
 ptr = malloc(laenge+1 + sizeof(sAbschnitt))
 if (ptr = NULL) return NULL; // kein freier Speicher vorhanden

 ptr-\>voriger = NULL;
 ptr-\>naechster = NULL;
 strcpy(ptr-\>text, txt);

 return ptr;
}

sAbschnitt \*finde\_letzten\_eintrag()
{
 sAbschnitt \*ptr = &Anfang;

 while (TRUE)
 {
 if (ptr-\>naechster == NULL) return ptr;
 ptr = ptr-\>naechster;
 }
}

int einfügen(char \*text)
{
 sAbschnitt \*ptr1, \*ptr2;

 ptr1 = neu(txt); 
 if (ptr1 == NULL) return -1; // Fehler

 ptr2 = finde\_letzten\_eintrag();

 ptr2-\>naechster = ptr1;
 ptr1-\>voriger = ptr2;
}

MfG Peter(TOO)

Hallo Peter!

Eine verkettete Liste wäre da wohl angebracht. Zudem solltest
du dich noch mit der dynamischen Speicherverwaltung etwas
auseinandersetzten.

Vielen Dank für den Hinweis. Auf die Idee bin ich noch nicht gekommen.
Das Ganze scheint mir aber doch relativ kompliziert. Außerdem bingt es nur dann eine Ersparnis an Speicherplatz, wenn weniger als die Hälfte des Platzes beansprucht wird, den ich in meiner Version mit den Zeiger-Arrays vorsehen würde.

War Dir eigentlich klar, dass es um C ++ geht? Ich meine, wegen malloc und Struct und so …
Das Prinzip funktioniert natürlich so oder so.

Gruß
Arndt

Hallo Arndt,

Eine verkettete Liste wäre da wohl angebracht. Zudem solltest
du dich noch mit der dynamischen Speicherverwaltung etwas
auseinandersetzten.

Vielen Dank für den Hinweis. Auf die Idee bin ich noch nicht
gekommen.
Das Ganze scheint mir aber doch relativ kompliziert. Außerdem
bingt es nur dann eine Ersparnis an Speicherplatz, wenn
weniger als die Hälfte des Platzes beansprucht wird, den ich
in meiner Version mit den Zeiger-Arrays vorsehen würde.

Das sehe ich aber nicht so.

  1. Die Text-Menge ist wohl immer die Gleiche.
  2. Die 2 Zeiger benötigen nur je 4 Byte, das sollte eigentlich wesentlich weniger sein als dein Text.
  3. Wenn du das fixe Arry nummst, muss der ganze Speicher schon beim Laden de Programms zur Verfügung gestellt werden.
  4. Bei wenig freiem Hauptspeicher muss deshalb gleich einiges, von Windows, in die Auslagerungs-Datei verlegt werden auch wenn gar nicht so viel Speicher für die Aufgabe benötigt wird.

War Dir eigentlich klar, dass es um C ++ geht? Ich
meine, wegen malloc und Struct und so …
Das Prinzip funktioniert natürlich so oder so.

Ja, schon aber ich beherrsche C wesentlich besser und da siehst du besser was eigentlich zu tun ist.
In C++ eledigt das new.

Hallo Peter!

Das sehe ich aber nicht so.

  1. Die Text-Menge ist wohl immer die Gleiche.

Klar.

  1. Die 2 Zeiger benötigen nur je 4 Byte, das sollte eigentlich
    wesentlich weniger sein als dein Text.

Darum geht es ja auch nicht.
Wenn mein Text nur aus einem Abschnitt besteht, benötigt der für Deine Lösung zusätzlich die zwei Zeiger.
Wenn ich als maximalen Umfang mal 100 Abschnitte festlege, muss ich ein Array von 100 Zeigern anlegen. Da ist Deine Version natürlich günstiger.

  1. Wenn du das fixe Arry nummst, muss der ganze Speicher schon
    beim Laden de Programms zur Verfügung gestellt werden.

Ja, aber nur der für ein Zeiger-Array.
Im obigen Beispiel ist die Version mit Verkettung günstiger, solange der Text tatsächlich weniger als 50 Abschnitte enthält. Denn yn diesem Punkt enthalten Deine 50 Abschnitte jeweils 2, also insgesamt 100 Zeiger, und Mein Array enthält (wie immer) ebenfalls 100 Zeiger. Wird der Text also größer, ist ein festes Array effizienter.

Jetzt ist die Frage, wie gut ich die Größe meiner „Texte“ abschätzen kann, und, wie groß jeweils der Verwaltungs-Aufwand ist.

Gruß
Arndt