Zeigerposition verschieben

Jacal

Mitglied
Hallo,

Ich habe aus einer Datei zwei Strukturen STest im Binärformat eingelesen und in den Void-Zeiger pFileData gespeichert.

Nun möchte ich beide folgendermaßen aus dem void-Zeiger "auslesen":
C++:
struct	STest	
{
	int	i1;
	int	i2;
};


int main ()
{	
	void	*pFileData;
	// ...

	STest	sTestFromFile1;
	STest	sTestFromFile2;

	// Im Void-Zeiger pFileData befinden sich zwei STest-Strukturen.
	// Diese sollen nach sTest1 und sTest2 kopiert werden.
	
	// Die erste Struktur befindet sich an der Anfangsposition des Zeigers.
	memcpy (&sTestFromFile1, pFileData, sizeof (STest));
	cout << "sTestFromFile1:\t" << sTestFromFile1.i1 << " " << sTestFromFile1.i2 << endl;

	// Die zweite Struktur beginnt an Stelle pFileData + sizeof (STest)
	memcpy (&sTestFromFile2, (&pFileData + sizeof (STest)), sizeof (STest));
	cout << "sTestFromFile2:\t" << sTestFromFile2.i1 << " " << sTestFromFile2.i2 << endl;
};

Allerdings wird hierbei sTest2FromFile2 nicht mehr richtig angezeigt.
Das Problem liegt denke ich beim Verschieben des Zeigers um sizeof (STest) Bytes.

Ich muss also die Adresse der Daten an Position Zeiger + xBytes richtig angeben, damit memcpy von dort aus die Daten beziehen kann.

Hat jemand eine Idee, wie ich das Anstelle?

Mfg, Jacal
 
Hallo,

in Zeile 24 holst du die Adresse des Zeigers und addierst sizeof(STest) auf diese anstatt auf den Zeiger selbst. Aber warum so kompliziert?
C++:
void *pFileData;
// ...

STest *pTests = static_cast<STest *>(pFileData);
STest sTestFromFile1 = pTests[0];
STest sTestFromFile2 = pTests[1];
Noch einfacher wäre es, wenn du nicht den Umweg über einen void-Zeiger machen würdest:
C++:
std::ifstream input("filename");
STest sTestFromFile1, sTestFromFile2;
input.read((char *)&sTestFromFile1, sizeof(STest));
input.read((char *)&sTestFromFile2, sizeof(STest));
input.close();

Grüße, Matthias
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

C++:
void *pFileData;
// ...

STest *pTests = static_cast<STest *>(pFileData);
STest sTestFromFile1 = pTests[0];
STest sTestFromFile2 = pTests[1];

Daran habe ich auch schon gedacht, nur will ich im nächsten Schritt weitere Strukturen in die Datei schreiben, auch mit Variabler größe, von daher brauche ich eine andere Methode.

Noch einfacher wäre es, wenn du nicht den Umweg über einen void-Zeiger machen würdest:
C++:
std::ifstream input("filename");
STest sTestFromFile1, sTestFromFile2;
input.read((char *)&sTestFromFile1, sizeof(STest));
input.read((char *)&sTestFromFile2, sizeof(STest));
input.close();


Das mit .read() ist genial... ich habe mich schon gefragt, warum es keine ifstream-Methode zum Bitweisen einlesen gibt, also habe extra einen Exkurs über die C FILE-Klasse (fread) verwendet, danke :)


Gibt es trotzdem noch eine Möglichkeit, an die memcpy die Adresse der Daten an Position Zeiger + xBytes zu übergeben?
in Zeile 24 holst du die Adresse des Zeigers und addierst sizeof(STest) auf diese anstatt auf den Zeiger selbst. Aber warum so kompliziert?
Wenn ich schreibe pFileData + sizeof (STest) bekomme ich einen Error: "void * Unbekannte Größe".


Edit:
Komisch, es funktioniert wenn ich die Position des Zeigers noch zusätzlich um 1 erhöhe:
C++:
memcpy (&sTestFromFile2, (&pFileData + sizeof (STest) + 1), sizeof (STest));

Aber springe ich dabei nicht theoretisch ein Byte zu weit?
Wenn der Zeiger zum Beispiel gerade auf das Byte 100 zeigt und STest 8 Bytes benötigt, dann nimmt die erste Struktur ja die Adressen 101, 102, 103, 104, 105, 106 und 107 ein. 100 + 8 wäre aber schon 108.
Wenn ich jetzt allerdings noch ein Byte weitergehe bin ich doch zu weit oder habe ich einen Denkfehler?
 
Zuletzt bearbeitet von einem Moderator:
Hi.
Gibt es trotzdem noch eine Möglichkeit, an die memcpy die Adresse der Daten an Position Zeiger + xBytes zu übergeben?

Wenn ich schreibe pFileData + sizeof (STest) bekomme ich einen Error: "void * Unbekannte Größe".
Mit einem void-Zeiger kann keine Zeigerarithmetik vollzogen werden. (Da die Größe des Objektes auf das der void-Zeiger zeigt nicht bekannt ist.)

Um den Zeiger um eine bestimmte Anzahl von Bytes zu verschieben, mußt du den void-Zeiger in einen Zeiger auf einen Typ casten, der 1 Byte groß ist. Die char Typen sind immer 1 Byte groß.

Gruß
 
Edit:
Komisch, es funktioniert wenn ich die Position des Zeigers noch zusätzlich um 1 erhöhe:
C++:
memcpy (&sTestFromFile2, (&pFileData + sizeof (STest) + 1), sizeof (STest));

Aber springe ich dabei nicht theoretisch ein Byte zu weit?
Du machst hier doch etwas völlig anderes. Du besorgst dir die Adresse der Zeigervariablen und addierst dort irgendwas drauf. D.h. der Adressoperator liefert einen Zeiger auf einen void-Zeiger und diese Adresse verschiebst du dann um sizeof(void*) * (sizeof(STest) + 1). Da kommt ganz bestimmt nichts sinnvolles raus.

Gruß
 
Hi.
Mit einem void-Zeiger kann keine Zeigerarithmetik vollzogen werden. (Da die Größe des Objektes auf das der void-Zeiger zeigt nicht bekannt ist.)

Um den Zeiger um eine bestimmte Anzahl von Bytes zu verschieben, mußt du den void-Zeiger in einen Zeiger auf einen Typ casten, der 1 Byte groß ist. Die char Typen sind immer 1 Byte groß.

Gruß

Vielen Dank, jetzt funktioniert es :)
 
Zurück