Alternative zu memcpy?
-
hallo,
wie fülle ich am besten ein struct?
ich hab das bisher immer mit memcpy gemacht, aber ich glaube nicht, dass das der beste weg ist.ich habe ein struct und ein byte-array.
wie bekomme ich jetzt am besten die (ungeordneten) daten aus dem array in mein struct?
ich weiß nicht, aber ich habe bisher in fremden quelltexten noch nie irgendwas mit memcpy gesehen, daher frag ich auch.
wie macht ihr das?
-
**** hallo **** schrieb:
ich habe ein struct und ein byte-array.
Was hat das miteinander zu tun?
**** hallo **** schrieb:
wie bekomme ich jetzt am besten die (ungeordneten) daten aus dem array in mein struct?
Keine Ahnung, was willst du erreichen?
-
TyRoXx schrieb:
**** hallo **** schrieb:
ich habe ein struct und ein byte-array.
Was hat das miteinander zu tun?
ja ich habe dieses byte-array (eine eingelesene datei halt), und ich will nun ein struct mit diesen daten füllen.
TyRoXx schrieb:
**** hallo **** schrieb:
wie bekomme ich jetzt am besten die (ungeordneten) daten aus dem array in mein struct?
Keine Ahnung, was willst du erreichen?
.... ähm... ja ich will dieses struct mit daten aus dem array füllen... ohne memcpy.
char ARRAY[]={0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x30}; struct zahlen{ int zahl1; int zahl2; int zahl3; int zahl4; };
ich will als ergebnis:
zahlen1.zahl1=0x04030201; // ARRAY[0] bis ARRAY[3] zahlen1.zahl2=0x08070605; // ARRAY[4] bis ARRAY[7] . . .
das hab ich bisher mit memcpy gemacht:
memcpy(&zahlen1.zahl1,&data[0],4);
was ist jetzt daran so schwer zu verstehen?
-
weitere ideen? schrieb:
dieses byte-array (eine eingelesene datei halt), und ich will nun ein struct mit diesen daten füllen.
Wieso liest du nicht gleich die Daten dahin, wo sie hinterher sein sollen?
das hab ich bisher mit memcpy gemacht:
Die ist schon klar, dass das Ergebnis dieser Aktion plattformabhängig ist?
-
SeppJ schrieb:
weitere ideen? schrieb:
dieses byte-array (eine eingelesene datei halt), und ich will nun ein struct mit diesen daten füllen.
Wieso liest du nicht gleich die Daten dahin, wo sie hinterher sein sollen?
weil es schneller und weniger fehleranfällig ist, wenn ich einmal fread mache als 100x fread?
SeppJ schrieb:
Die ist schon klar, dass das Ergebnis dieser Aktion plattformabhängig ist?
ja das hats mit c so ansich. alternavivorschläge?
-
SeppJ schrieb:
Wieso liest du nicht gleich die Daten dahin, wo sie hinterher sein sollen?
SeppJ hat recht ...
Alternativ gehts auch umgekehrt. Teile des Arrays als Struktur casten, wozu umkopieren wenn das Layout der Struktur erwartet wird ?
Gerade bei Dateiformaten sollten Leseroutinen allerdings eigentlich plattformunabhängig sein.
-
merano schrieb:
SeppJ schrieb:
Wieso liest du nicht gleich die Daten dahin, wo sie hinterher sein sollen?
SeppJ hat recht ...
Alternativ gehts auch umgekehrt. Teile des Arrays als Struktur casten, wozu umkopieren wenn das Layout der Struktur erwartet wird ?
Gerade bei Dateiformaten sollten Leseroutinen allerdings eigentlich plattformunabhängig sein.
ans casten hab ich auch schon gedacht, aber das struct-padding des gcc macht dies leider schwer.
-
struct-padding _/ schrieb:
ans casten hab ich auch schon gedacht, aber das struct-padding des gcc macht dies leider schwer.
Aber memcpy benutzen?
Da passiert doch technisch gesehen das gleiche!
Um mal produktiv zu sein:
Fall 1: Portabilität soll gewahrt bleiben (Padding, Endianess, Größe der Datentypen, usw. können dies negativ beeinflussen). Dann kannst du das ganze Binärgefrickel sowieso vergessen. Du brauchst ein vernünftiges Dateiformat und einen richtigen Parser dafür. Dies ist sicherlich eine gute Methode, denn wen interessiert ein Millisekundenvorteil beim Lesen, wenn es dafür unzuverlässig ist? Dafür müsstest du dein ganzes Programm umkrempeln und auch die ganze Art und Weise ändern, wie du über Daten denkst.
Fall 2: Portabilität ist scheißegal, dieses Programm soll nur Binärdaten lesen, die genau mit diesem Programm in dieser Version, mit diesem Build geschrieben wurden. Dann hast du bereits deine Lösung. memcpy vs. Cast ist technisch kein Unterschied, solange es nicht sehr große Datenmengen am Stück sind. Dann hätte eventuell (aber nicht unbedingt, ich könnte mir vorstellen, dass ein Compiler dies optimieren kann) memcpy einen Vorteil. Jedoch lege ich dir nochmals nahe, keinen Zwischenpuffer zu benutzen. Deine zwei Einwände kann ich nicht nachvollziehen:weniger fehleranfällig ist, wenn ich einmal fread mache als 100x fread?
Und wo ist der Unterschied in der Fehleranfälligkeit, wenn du hinterher 100x memcpy machst? Das ist doch beides Mal die gleiche Art von Aktion, bloß dass die Daten einmal alle hintereinander in der Datei stehen und das andere Mal im Speicher. Das ist doch programmiertechnisch kein Unterschied!
schneller
Probier das erst einmal aus. Würde mich in diesem Fall eher wundern. Ich würde sogar eher darauf tippen, dass es mit dem Zwischenspeicher langsamer ist, schließlich ist es eine unnötige Zwischenstation. Falls du einen großen Unterschied feststellen solltest, möchte ich gerne Code sehen, dann machst du nämlich wahrscheinlich irgendwo etwas suboptimal. Weiterhin:
SeppJ schrieb:
wen interessiert ein Millisekundenvorteil beim Lesen
?
-
aha schrieb:
weil es schneller und weniger fehleranfällig ist,
Man sieht an deinem Code, dass dem eben nicht so ist. Je mehr Code du schreibst, desto mehr Fehler sind drin.
aha schrieb:
wenn ich einmal fread mache als 100x fread?
Wieviele Terabyte Daten liest du denn, dass du signifikante Zeitunterschiede erwartest? Ein Aberglauben vieler Anfänger, die meinen, durch eigene Code"optimierungen" das Programm verbessern zu müssen, dabei aber die eigentliche Aufgabenstellung ignorieren und auch noch massenhaft Fehler einbauen.
Schreib doch erstmal ein funktionsfähiges Programm, optimieren kannst du dann immer noch.
Deine Probleme rühren von unkoordiniertem bzw. gänzlich fehlendem Programmdesign her, du frickelst Bottom-Up rum anstatt Top-Down. (auch wieder ein klassischer Anfängerfehler)aha schrieb:
SeppJ schrieb:
Die ist schon klar, dass das Ergebnis dieser Aktion plattformabhängig ist?
ja das hats mit c so ansich. alternavivorschläge?
Deutsch kannst du aber schon, oder? Sieht aber nicht so aus.
C kapselt die Schnittstellen der jeweiligen Plattform und arbeitet somit zunächst mal plattformunabhängig, und geht, im Gegensatz vieler anderer Laiensprachen davon aus, dass der Entwickler weiß was er tut, in deinem Fall musst du also wissen, wer oder was Byteorder bedeutet und wie man mit C-Mitteln diese verarbeitet.
-
SeppJ schrieb:
struct-padding _/ schrieb:
ans casten hab ich auch schon gedacht, aber das struct-padding des gcc macht dies leider schwer.
Aber memcpy benutzen?
Da passiert doch technisch gesehen das gleiche!
naja ich lese jedes struct-element einzeln ein... also wenn ein struct 5 elemente hab, hab ich am ende 5 memcpys...
also wie würdet ihr das jetzt machen? direct casten( was definitiv die einfachere methode ist), oder memcpy aufrufen?
wie machen es denn anwendungen, z.b. der linuxkernel? die dateisysteme dort werden ja auch durch structs implementiert. wird da etwas mit memcpy eingelsen oder direkt gecastet? weiß das jemand?
?
-
Wutz schrieb:
aha schrieb:
weil es schneller und weniger fehleranfällig ist,
Man sieht an deinem Code, dass dem eben nicht so ist. Je mehr Code du schreibst, desto mehr Fehler sind drin.
aha schrieb:
wenn ich einmal fread mache als 100x fread?
Wieviele Terabyte Daten liest du denn, dass du signifikante Zeitunterschiede erwartest? Ein Aberglauben vieler Anfänger, die meinen, durch eigene Code"optimierungen" das Programm verbessern zu müssen, dabei aber die eigentliche Aufgabenstellung ignorieren und auch noch massenhaft Fehler einbauen.
Schreib doch erstmal ein funktionsfähiges Programm, optimieren kannst du dann immer noch.
Deine Probleme rühren von unkoordiniertem bzw. gänzlich fehlendem Programmdesign her, du frickelst Bottom-Up rum anstatt Top-Down. (auch wieder ein klassischer Anfängerfehler)aha schrieb:
SeppJ schrieb:
Die ist schon klar, dass das Ergebnis dieser Aktion plattformabhängig ist?
ja das hats mit c so ansich. alternavivorschläge?
Deutsch kannst du aber schon, oder? Sieht aber nicht so aus.
C kapselt die Schnittstellen der jeweiligen Plattform und arbeitet somit zunächst mal plattformunabhängig, und geht, im Gegensatz vieler anderer Laiensprachen davon aus, dass der Entwickler weiß was er tut, in deinem Fall musst du also wissen, wer oder was Byteorder bedeutet und wie man mit C-Mitteln diese verarbeitet.ja ich weiß was big und little endian sind.
also deine beiträge werden auch immer herablassender und arroganter, und enthalten meist wenig inhalt.
wollt ich nur mal gesagt haben
also was ist jetzt?
-
struct zahlen zahlen1; ... size_t result = fread(&zahlen1, sizeof(zahlen1), 1, mystream); ...
-
Belli schrieb:
struct zahlen zahlen1; ... size_t result = fread(&zahlen1, sizeof(zahlen1), 1, mystream); ...
ja, aber auch hier ist das problem mit dem struct-padding nicht gelöst.
-
Ich habe oben noch etwas Relevantes in meinen Beitrag reineditiert. Ich hatte nicht erwartet, dass der Thread so schnell wächst.
-
ok, danke für die bisherigen antworten.
aber ich weiß nach wie vor nicht, was der "profi" weg ist.
daher hier nochmal ein praktisches beispiel:struct zahlen{ int zahl1; int zahl2; char zahl3; char zahl4[3]; }; char datei[]={0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20};
das ist die ausgangslage. ich habe ein struct, und ich habe eine datei (--> byte-array). nun sollen daten aus dem array "datei" in ein struct vom typ "zahlen".
ich hätte jetzt jedes einzelne element mit memcpy eingelesen. aber anscheinend ist dies nicht der richtige weg?
vorschlag mit dem casten:
struct zahlen struct1=(zahlen) data;
das ist zwar ein einfacher und unkomplizierter weg, allerdings könnte es probleme mit struct-padding geben.
also was jetzt?
-
ja ok, aber... schrieb:
Belli schrieb:
struct zahlen zahlen1; ... size_t result = fread(&zahlen1, sizeof(zahlen1), 1, mystream); ...
ja, aber auch hier ist das problem mit dem struct-padding nicht gelöst.
Das ist hier genau so gut gelöst, wie bei memcpy, und dazu wurde eine Alternative gesucht!
-
Belli schrieb:
ja ok, aber... schrieb:
Belli schrieb:
struct zahlen zahlen1; ... size_t result = fread(&zahlen1, sizeof(zahlen1), 1, mystream); ...
ja, aber auch hier ist das problem mit dem struct-padding nicht gelöst.
Das ist hier genau so gut gelöst, wie bei memcpy, und dazu wurde eine Alternative gesucht!
ja das ist richtig, aber ich lese jedes element einzeln ein!
bitte meinen vorherigen post nicht übersehen!
-
Dann lies hier auch jedes Element einzeln ein:
fread(&zahlen1.zahl1, ...
-
Belli schrieb:
Dann lies hier auch jedes Element einzeln ein:
fread(&zahlen1.zahl1, ...
ja, ich suche hier alternativvorschläge.
mein gott, wie machen es denn andere programmierer? ich hab noch nie irgendwo gesehen, dass jedes element einzeln eingelesen wird!
bin ich denn der erste, der probleme mit diesem struct-padding hat?
-
Mach dich mal klar darüber, dass das struct-Padding bei den Methoden...
a) jedes struct direct über fread füllen
b) mit fread gelesenes bytearray via memcpy in struct kopieren
c) struct-Zeiger zeigt auf mit fread gelesenes bytearray... immer genau das gleiche Problem ist. Entweder deine Definition der struct passt oder halt nicht.