Seite 1 von 1

[c++] Struct in Array aus datei

Verfasst: 13.01.2011, 09:52
von TheBenji
Hallo,

man kann ja ganze Instanzen von Klassen in Datein speichern, das ist auch soweit kein Problem :)
Ich habe jetzt aber eine Klasse mit einem Array...das structs aufnimmt.
Wenn ich diese jetzt in einer Datei speichere und dann wieder auslesen möchte kommt bei zweiterem ein Segmentaion fault...
Ich kann auf alles in der Klasse zugreifen, nur nicht auf das array, wodran liegt das? bzw. was kann ich machen damit ich auch diesen speicher zugreifen darf...?

Grüße

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 09:56
von joggel
Ich glaube bei Arrays ist das Problem, das Arrays als Zeiger betrachtet werden.... vlt. kann das jemand anders besser/richtig erklären.
Wenn ich den Inhalt von Array speicher würde, würde ich über das Array gehen, und alle Elemente einzeln speichern beim einlesen ebenfalls, also nur andersherum, sprich, du müsstest noch die Anzahl der Array-Elemente mit in die Datei speichern.

Hoffe das hilft Dir weiter!

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 10:22
von Schrompf
Alles, was kein primitiver Datentyp ist (float, int, char, NICHT char*), kann in eine Datei geschrieben werden. Für alles andere musst Du besonderen Code schreiben, der Anzahl und die einzelnen Elemente schreibt. Ein Array (oder in eine Klasse verpackt als Vector, Liste oder sonstwas) besteht aus Zeigern. Zeiger sind Speicheradressen. Wenn Du die wieder lädst, steht an der Stelle im Speicher eh schon was ganz anderes oder gar nix.

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 10:31
von TheBenji
Okay, danke für die Antworten.
Das bedeutet also wenn ich das abspeichern will muss ich das struct auseinander nehmen und speichern und diese so sortieren das ich die nachher wieder zu einem array zusammenbauen kann?!

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 10:39
von joggel
Nun ja, es kommt darauf an, wie dein Struct aussieht.
Wenn dein Struct irgendwelche Zeiger enthält musst Du was machen...
Soweit ich deinen obigen Post verstanden habe, hast Du ein Array aus deinen Structs,also sowas wie:

Code: Alles auswählen

MyStruct structArray[10];
Wenn Du nun die 10 Elemente speichern willst, speicherst Du in die Datei die Anzahl der Elemente ==> 10.
Dann sowas wie

Code: Alles auswählen

for(int index(0); index<10; ++index)
{
 writeToFile(file,structArray[index]);
}
Aber wie gesagt, es kommt darauf an wie dein Struct aussieht...

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 10:42
von TheBenji
in dem struct selbst sind eig. auch abstracte klassen aber die kann ich problemlos auslagern was ich wenn ich so drüber nachdenke so oder so machen werde.
Sprich es wird wohl eig. nur ein paar integer werte geben.

Werde es dann erstmal so versuchen ;)

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 11:21
von kimmi
Such doch mal nach Serialisierung von Klassen. Da findest du sicher noch einige weitere Denkanstöße.

Gruß Kimmi

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 12:34
von dowhilefor
man kann ja ganze Instanzen von Klassen in Datein speichern, das ist auch soweit kein Problem
Äh moment ... ich hab das gefühl du speicherst deine Klasse so wie sie ist direkt in eine datei, ist das richtig?
Also so in der Art?

Code: Alles auswählen

// ...
MyClass class;
fwrite (&class , 1 , sizeof(MyClass) , pFile );
Weil das ist ganz schnell ganz großer Murks, du kannst eine Klasse nicht einfach in einem Rutsch serialisieren, sondern musst, wie schon erwähnt wurde, die einzelnen Komponenten der Klasse serialisieren.

Falls du das schon weißt oder bedacht hast, ignorier mein Post :)

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 14:34
von BeRsErKeR
Schrompf hat geschrieben:Alles, was kein primitiver Datentyp ist (float, int, char, NICHT char*), kann in eine Datei geschrieben werden.
Ich glaub da ist ein "kein" zu viel oder es fehlt ein "nicht". Nur um Verwirrungen zu vermeiden. ;)

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 14:43
von Krishty
TheBenji hat geschrieben:Ich habe jetzt aber eine Klasse mit einem Array...das structs aufnimmt.
Dynamisches oder statisches Array, vielleicht auch Container?
joggel hat geschrieben:Ich glaube bei Arrays ist das Problem, das Arrays als Zeiger betrachtet werden.... vlt. kann das jemand anders besser/richtig erklären.
Auf Arrays greift man oft per Zeiger zu. Dynamische Arrays sind ausschließlich per Zeiger adressierbar. D.h. wenn man ein dynamisches Array allokiert hat, speichert man meist nur den Zeiger dorthin; nicht das Array selber (weil man es ja dann nicht erst allokieren müsste).
Schrompf hat geschrieben:Ein Array […] besteht aus Zeigern.
Doppelt falsch – ein Array ist ein Stück Speicher und so lange es kein Array von Zeigern ist, kommen keine Zeiger drin vor. Auch statische Arrays lassen sich 1:1 in die Datei schreiben und wieder auslesen … jedenfalls wenn wir von sowas wie int array[1024]; file.write(array, sizeof(array)); sprechen.
TheBenji hat geschrieben:in dem struct selbst sind eig. auch abstracte klassen
Du darfst nur POD (Plain old Data; Typen ohne virtuelle Funktionen) in Dateien schreiben – abstrakte Klassen (falls wir hier beide von Klassen sprechen, die virtuelle Funktionen besitzen) bestehen intern aus Zeug, was sich nicht in eine Datei schreiben und wieder auslesen lässt.
dowhilefor hat geschrieben:Äh moment ... ich hab das gefühl du speicherst deine Klasse so wie sie ist direkt in eine datei, ist das richtig? […] Weil das ist ganz schnell ganz großer Murks, du kannst eine Klasse nicht einfach in einem Rutsch serialisieren, sondern musst, wie schon erwähnt wurde, die einzelnen Komponenten der Klasse serialisieren.
Falls es sich um eine POD-Klasse handelt, ist das vollkommen gültig.

@OP: Du hast die Frage auf denkbar ungünstigste Art und Weise gestellt: Wir wissen nicht,
  • Wie deine Klasse aussieht (POD?)
  • Was du benutzt, um die Datei zu schreiben (fwrite, ::std::ofstream, …?)
  • Ob dein Array ein statisches Array, ein dynamisches Array oder ein Container ist
und darum ist
kimmi hat geschrieben:Such doch mal nach Serialisierung von Klassen.
der einzig sinnvolle Vorschlag.

Gruß, Ky

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 15:00
von joggel
Krishty hat geschrieben:
TheBenji hat geschrieben:in dem struct selbst sind eig. auch abstracte klassen
Du darfst nur POD (Plain old Data; Typen ohne virtuelle Funktionen) in Dateien schreiben – abstrakte Klassen (falls wir hier beide von Klassen sprechen, die virtuelle Funktionen besitzen) bestehen intern aus Zeug, was sich nicht in eine Datei schreiben und wieder auslesen lässt.
Alsooooo:
Ich will deine Kompetenz nicht in Frage stellen, aber das werde ich bei Gelegenheit mal in der Praxis probieren!!
Wenn ich eine Klasse "in eine Datei schreibe", die eine abstrakten Klasse ist, dann bin ich mir fast sicher, das das gut geht.
Vorausgesetz diese abstrakte (Basis-)Klasse enthält eben elementare Daten (int, float,...).

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 15:07
von Biolunar
joggel hat geschrieben:
Krishty hat geschrieben:
TheBenji hat geschrieben:in dem struct selbst sind eig. auch abstracte klassen
Du darfst nur POD (Plain old Data; Typen ohne virtuelle Funktionen) in Dateien schreiben – abstrakte Klassen (falls wir hier beide von Klassen sprechen, die virtuelle Funktionen besitzen) bestehen intern aus Zeug, was sich nicht in eine Datei schreiben und wieder auslesen lässt.
Alsooooo:
Ich will deine Kompetenz nicht in Frage stellen, aber das werde ich bei Gelegenheit mal in der Praxis probieren!!
Wenn ich eine Klasse "in eine Datei schreibe", die eine abstrakten Klasse ist, dann bin ich mir fast sicher, das das gut geht.
Vorausgesetz diese abstrakte (Basis-)Klasse enthält eben elementare Daten (int, float,...).
Falsch, damit erzeugst du undefiniertes Verhalten! Alles was kein POD ist, darf vom Compiler mit „unsichtbarem“ Zeug beschmückt werden.

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 15:15
von Krishty
Ich kann es dir jetzt nicht demonstrieren (habe gerade keinen Compiler hier), aber die Erklärung ist:

Wenn eine Methode virtual deklariert ist, speichert der Compiler sie in einer Virtual Function Table. Funktionen liegen auch nur im Speicher und man kann sie per Zeiger adressieren, und genau das tut der Compiler auch in dieser Tabelle: Hast du eine Klasse mit drei virtuellen Funktionen, dann legt der Compiler für diese Klasse eine Virtual Function Table an, die drei Funktionszeiger enthält, die auf die überschriebenen Versionen der Funktionen im Programmspeicher zeigen. Die Klasse selber bekommt als erstes, unsichtbares Attribut einen Zeiger auf diese Tabelle. Rufst du eine virtuelle Funktion auf, wird über das unsichtbare erste Zeigerattribut die VFT geladen; darin schaut der Compiler dann nach, wo die tatsächliche Funktion liegt, die du aufrufst, und ruft sie auf – dadurch wird immer die richtige Funktion aufgerufen, auch, wenn der Compiler den Typ des Objekts zum Zeitpunkt der Kompilierung nicht kennt (denn eine Ableitung hätte z.B. einen anderen VFT, in dem einige Funktionen überschrieben sind, also wanders hinzeigen). (Darum sind virtual deklarierte Funktionen ein bisschen langsamer.)

Der Knackpunkt ist, dass diese Tabelle nicht immer an derselben Position im Speicher liegen muss. Wenn du dein Programm zwei Mal startest, liegt es mit großer Wahrscheinlichkeit an zwei unterschiedlichen Adressen. (Das wird seit Vista sogar erzwungen und ist ein Sicherheitsfeature, weil es für Angreifer bedeutend schwerer wird, eine Sicherheitslücke auszunutzen, wenn sie nicht sagen können, wo im Speicher das Programm bei der Ausführung liegen wird.)

Wenn du also deine Klasse mit virtuellen Funktionen in eine Datei schreibst, schreibst du unwissentlich den unsichtbaren Zeiger auf die VFT mit in die Datei. Und beim nächsten Mal liest du ihn auch wieder aus. Wenn du dann eine virtuelle Methode des Objekts aufrufen willst, wird versucht, ihre Adresse in der VFT nachzuschlagen – aber da steht nun die Adresse, die die VFT hatte, als du das Objekt in die Datei geschrieben hattest. Und die ist mit an Sicherheit grenzender Wahrscheinlichkeit ungültig und du hast eine Zugriffsverletzung.

Das Beispiel ist aber nur für die Kategorie „Gut zu wissen“ – wie der Compiler virtuelle Methoden implementiert ist nicht vorgeschrieben und darum ist es generell vom Standard verboten, Klassen mit virtuellen Methoden bitweise zu speichern/kopieren/laden.

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 17:11
von TheBenji
WOW - danke für diese zahlreichen Antworten.

Ich denke ihr habt mir schon sehr weitergeholfen und ich habe genug denkanstöße um das jetzt selbt sinnvol umzusetzen ;)

Danke an alle^^

Re: [c++] Struct in Array aus datei

Verfasst: 13.01.2011, 17:26
von dowhilefor
Krishty, mal schnell ein Lob für die Erklärung :) Hab lange überlegt wie ich es ausdrücke und musste dann doch weiter arbeiten. Schön das du es so gut verständlich auf den Punkt gebracht hast!

Vote for FAQ