# Zeigerposition verschieben



## Jacal (8. Mai 2009)

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":

```
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


----------



## Matthias Reitinger (8. Mai 2009)

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?

```
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:

```
std::ifstream input("filename");
STest sTestFromFile1, sTestFromFile2;
input.read((char *)&sTestFromFile1, sizeof(STest));
input.read((char *)&sTestFromFile2, sizeof(STest));
input.close();
```

Grüße, Matthias


----------



## Jacal (8. Mai 2009)

Matthias Reitinger hat gesagt.:


> Hallo,
> 
> 
> ```
> ...



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.



Matthias Reitinger hat gesagt.:


> Noch einfacher wäre es, wenn du nicht den Umweg über einen void-Zeiger machen würdest:
> 
> ```
> std::ifstream input("filename");
> ...




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:

```
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?


----------



## deepthroat (8. Mai 2009)

Hi.





Jacal hat gesagt.:


> 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ß


----------



## deepthroat (8. Mai 2009)

Jacal hat gesagt.:


> *Edit:*
> Komisch, es funktioniert wenn ich die Position des Zeigers noch zusätzlich um 1 erhöhe:
> 
> ```
> ...


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ß


----------



## Jacal (8. Mai 2009)

deepthroat hat gesagt.:


> 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ß.
> ...



Vielen Dank, jetzt funktioniert es


----------

