Forum: PC-Programmierung C++ array aus structs kopieren


von Victoria (Gast)


Lesenswert?

liebe kollegen!

ich würde gerne ein array aus structs kopieren. leider geht das nicht so 
wie ich es gerne hätte. kann mit jemand vielleicht einen tipp geben?
1
...
2
  typedef struct SiftKeypoint
3
  {
4
    float x, y, s, o; 
5
  }SiftKeypoint;
6
...
7
8
SiftKeypoint myKeys[3];
9
...
10
memcpy(*&keys, &myKeys, sizeof(myKeys)*3);

keys wird mit der funktion
1
addf->ReadKeys(&myKeys, "../data/testkeys.txt");
aufgerufen.

DANKE FÜR DIE HILFE!!!

Vic

von Peter II (Gast)


Lesenswert?

Victoria schrieb:
> keys wird mit der funktion
>
1
> addf->ReadKeys(&myKeys, "../data/testkeys.txt");
2
>
> aufgerufen.

und Wo ist die Funktion ReadKeys?

> memcpy(*&keys, &myKeys, sizeof(myKeys)*3);

also ein *& macht für mich keinen sinn.

von Quack (Gast)


Lesenswert?

Hier fehlt.

a) ein komplettes Stueck Code, auf den Fehler reduziert
b) eine Anleitung, wie der Fehler zu reproduzieren ist
c) den Fehler

*&keys sieht nicht sehr vertrauenerweckend aus. Was moechtest du damit 
erreichen?

von Matthias L. (Gast)


Lesenswert?

Das hier:
1
sizeof(myKeys)

gibt dir die Länge des kompletten Arrays zurück. ALso ist das *3 
höchstwahrscheinlich fehl am Platz.
1
memcpy( &keys, &myKeys, sizeof(myKeys) );
Kopiert das Array myKeys an die Adresse keys.

von Victoria (Gast)


Lesenswert?

das & ist wegen dem struct.
der * wegen dem pointer.

wenn ich den code ohne Array (also nur das struct) ausprobiere 
funktioniert die Version mit *&.
1
memcpy(*&keys, &myKeys, sizeof(myKeys));

von Peter II (Gast)


Lesenswert?

Victoria schrieb:
> das & ist wegen dem struct.
> der * wegen dem pointer.

wo hast du das denn gelernt?

von Victoria (Gast)


Lesenswert?

hier
http://www.cplusplus.com/reference/cstring/memcpy/

der * ist da weil ich mit pointern arbeite

von Victoria (Gast)


Lesenswert?

kann es sein, dass mein memcpy nicht funktioniert weil ich sizeof 
verwende?

von Peter II (Gast)


Lesenswert?

Victoria schrieb:
> kann es sein, dass mein memcpy nicht funktioniert weil ich sizeof
> verwende?

warum sollte das so sein, sizeof liefert eine zahl, memcpy braucht eine 
zahl also funktioniert es. Die Frage ist ob es die richtige zahl ist, 
dafür müsste man aber wirklich mehr code code sehen.

> hier
> http://www.cplusplus.com/reference/cstring/memcpy/
> der * ist da weil ich mit pointern arbeite

dort wird aber nirgends ein *& verwendet?

von Victoria (Gast)


Lesenswert?

die haben auch keine pointer.

Der code mit *& funktioniert wenn ich keine Arrays verwende.

von Udo S. (urschmitt)


Lesenswert?

Victoria schrieb:
> hier
> http://www.cplusplus.com/reference/cstring/memcpy/

Victoria schrieb:
> kann es sein, dass mein memcpy nicht funktioniert weil ich sizeof
> verwende?

Du hast doch den Link selbst genannt. Da sind sogar 2 Aufrufe mit 
sizeof() im Beispiel. Liest du auch die Links die du postet?

So wird das nix, du brauchst ein C Buch und musst es auch durcharbeiten.

von Peter II (Gast)


Lesenswert?

Victoria schrieb:
> die haben auch keine pointer.
>
> Der code mit *& funktioniert wenn ich keine Arrays verwende.

klar geht das du kannst auch *&*&*&*&*&*&*& schreiben, das wird auch 
gehen - macht nur keinen sinn.

von Victoria (Gast)


Lesenswert?

ja, den link habe ich gelesen. deshalb funktioniert der code auch wenn 
ich nur ein struct kopieren will. Das *& funktioniert genau so wie es 
soll.

mein Problem ist, dass ich ein Array gefüllt mit structs kopieren 
möchte.

von Peter II (Gast)


Lesenswert?

Victoria schrieb:
> ja, den link habe ich gelesen. deshalb funktioniert der code auch wenn
> ich nur ein struct kopieren will. Das *& funktioniert genau so wie es
> soll.

dann lass es doch mal weg und du wirst sehen es geht immer noch.

von Udo S. (urschmitt)


Lesenswert?

Victoria schrieb:
> Das *& funktioniert genau so wie es
> soll.

Klar -(-x)) funktioniert auch und gibt x.
Dein Problem ist und bleibt ein C Buch.

von Victoria (Gast)


Lesenswert?

könnten wir beim thema bleiben und das *& vergessen?

mein problem ist:
ich würde gerne ein array aus structs kopieren.
EGAL WIE!

von Quack (Gast)


Lesenswert?

Hier fehlt:

a) ein komplettes Stueck Code, auf den Fehler reduziert
b) eine Anleitung, wie der Fehler zu reproduzieren ist
c) die Fehlerbeschreibung

von Dr. Sommer (Gast)


Lesenswert?

Victoria schrieb:
> ich würde gerne ein array aus structs kopieren.

Verwende einfach std::array und operator = :
1
#include <array>
2
3
int main () {
4
  // Ein Struct-Array anlegen
5
  std::array<ShiftKeypoint, 3> myKeys;
6
  
7
  // myKeys befüllen oder so
8
  addf->ReadKeys(myKeys.data (), "../data/testkeys.txt");
9
  
10
  // Zweites array anlegen
11
  std::array<ShiftKeypoint, 3> keys;
12
  
13
  // Array kopieren.
14
  keys = myKeys;
15
}

von Peter II (Gast)


Lesenswert?

Victoria schrieb:
> könnten wir beim thema bleiben und das *& vergessen?
>
> mein problem ist:
> ich würde gerne ein array aus structs kopieren.
> EGAL WIE!

das geht ohne Probleme mit memcpy, aber du zeigt uns ja kein 
vollständigen code, damit kann man da nicht weiter helfen.

von Dr. Sommer (Gast)


Lesenswert?

Peter II schrieb:
> das geht ohne Probleme mit memcpy, aber du zeigt uns ja kein
> vollständigen code, damit kann man da nicht weiter helfen.
Ist aber überflüssig, da er ja C++ verwendet geht das einfacher mit 
std::array oder std::vector und Zuweisungsoperator.

von O.T.roll (Gast)


Lesenswert?

Victoria schrieb:
> EGAL WIE!
1
typedef struct SiftKeypoint
2
  {
3
    float x, y, s, o; 
4
  }SiftKeypoint;
5
6
SiftKeypoint myKeys[3];
7
SiftKeypoint keys[3];
8
9
for(int i = 0; i<3; i++)
10
{
11
  keys[i].x = myKeys[i].x;
12
  keys[i].y = myKeys[i].y;
13
  keys[i].s = myKeys[i].s;
14
  keys[i].o = myKeys[i].o;
15
}

von Peter II (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Ist aber überflüssig, da er ja C++ verwendet geht das einfacher mit
> std::array oder std::vector und Zuweisungsoperator.

woran erkennst du das?

> addf->ReadKeys(&myKeys, "../data/testkeys.txt");

gibt es auch in C mit structs und funktionszeigern.

von Dr. Sommer (Gast)


Lesenswert?

Peter II schrieb:
> woran erkennst du das?
Am Thread-Titel.

von Peter II (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Peter II schrieb:
>> woran erkennst du das?
> Am Thread-Titel.

währe ja nicht das erste mal das am ende sogar C++/CLI  gemeint ist.

von Dr. Sommer (Gast)


Lesenswert?

Peter II schrieb:
> währe ja nicht das erste mal das am ende sogar C++/CLI  gemeint ist.
Ich glaub auch da gibt es den operator =.

von Charlie (Gast)


Lesenswert?

memcpy erwartet als erste  zwei Parameter Zeiger auf Speicheraddressen 
aus denen gelesen, bzw. geschrieben werden soll.
Ein Array in C ist aber bereits nichts anderes als ein Zeiger.
Dementsprechend muesste dein memcpy-Code so aussehen:
1
  typedef struct SiftKeypoint
2
  {
3
    float x, y, s, o; 
4
  }SiftKeypoint;
5
//...
6
7
SiftKeypoint myKeys[3];
8
//...
9
memcpy( keys, myKeys, sizeof( ShiftKeypoint )*3 );

von Victoria (Gast)


Lesenswert?

danke dr. sommer, das funktioniert.

von fibonacci de gogolores (Gast)


Lesenswert?

Ist ein &* das gleiche wie ein *& ?

von Karl H. (kbuchegg)


Lesenswert?

fibonacci de gogolores schrieb:
> Ist ein &* das gleiche wie ein *& ?


Die Frage kann man durch nachdenken lösen.
Das heisst, sofern man weiß, was die Zeichen & bzw * in diesem 
Zusammenhang bedeuten.

Hat ein Wert, zb 5, eine Adresse im Speicher?

: Bearbeitet durch User
von fibonacci de gogolores (Gast)


Lesenswert?

Der *Operator dereferenziert einen Zeiger, damit greife ich als auf den 
Speicherinhalt derjenigen Adresse zu auf die der Zeiger verweist.

Der &Operator ermittelt die Adresse beispielsweise einer Variablen.

Das kann aber eigentlich ja nicht die ganze Wahrheit sein, oder?
Oder wie kommt es dass die Deklaration eines Zeigers ebenfalls den 
*Operator erfordert? Wie z.B. so int* zeiger = &i;
Wurde das einfach so festgelegt bei der Entwicklung von C/C++ oder 
gibt's da einen tieferen Sinn dahinter?

Eine 5 kann schon eine Adresse im Speicher haben. Wie sie dort hinkommt 
ist dann eine andere Frage.

Zum *&
z.B. *&k da dereferenziere ich die Adresse von k greife als auf den 
Inhalt von k zu. Also eigentlich das gleiche wie wenn ich nur k 
schreiben würde.
Also ist i = *&k und i = k das gleiche.

Ich habe auch schon Dinge gesehen wie *&*k oder **&k was ist das dann?

von Mark B. (markbrandis)


Lesenswert?

fibonacci de gogolores schrieb:
> Das kann aber eigentlich ja nicht die ganze Wahrheit sein, oder?
> Oder wie kommt es dass die Deklaration eines Zeigers ebenfalls den
> *Operator erfordert? Wie z.B. so int* zeiger = &i;

Woher soll der Compiler wissen, ob Du eine Integer-Variable oder einen 
Zeiger auf eine Integer-Variable anlegen willst? Das muss man ihm auf 
irgendeine Art mitteilen. Insofern ist der * bei der Deklaration eines 
Zeigers eben kein Dereferenzierungsoperator, sondern teilt dem Compiler 
mit "das hier soll ein Zeiger sein".

von Kindergärtner (Gast)


Lesenswert?

fibonacci de gogolores schrieb:
> Der &Operator ermittelt die Adresse beispielsweise einer Variablen.
Einer Variablen oder Funktion, sonst nix.

fibonacci de gogolores schrieb:
> Oder wie kommt es dass die Deklaration eines Zeigers ebenfalls den
> *Operator erfordert? Wie z.B. so int* zeiger = &i
Da ist das kein Operator, sondern Deklarationssyntax, und hat nichts mit 
dem Dereferenzierungsoperator zu tun, sondern ist nur zufällig das 
gleiche Zeichen. Die Typ-Syntax von C, und noch mehr bei C++, ist leider 
ziemlich verkorkst.

fibonacci de gogolores schrieb:
> Wurde das einfach so festgelegt bei der Entwicklung von C/C++
Ja
> oder gibt's da einen tieferen Sinn dahinter?
Ja, Anfänger verwirren...

fibonacci de gogolores schrieb:
> Eine 5 kann schon eine Adresse im Speicher haben.
Nein, eine 5 ist nur ein temporärer Wert der gar nicht im Speicher 
landen muss, und hat daher auch keine Adresse.
> Wie sie dort hinkommt ist dann eine andere Frage.
Das ist aber die zentrale Frage; der Compiler packt nicht einfach eine 5 
irgendwohin, das muss man wenn schon explizit machen (d.h. die 5 in eine 
Variable packen, und die Adresse der Variable abfragen).

fibonacci de gogolores schrieb:
> z.B. *&k da dereferenziere ich die Adresse von k greife als auf den
> Inhalt von k zu. Also eigentlich das gleiche wie wenn ich nur k
> schreiben würde.
Jup.

fibonacci de gogolores schrieb:
> Ich habe auch schon Dinge gesehen wie *&*k oder **&k was ist das dann?
In C++ gibts da noch eine zusätzliche Gemeinheit, denn man kann den 
&-Operator und den *-Operator einer Klasse überladen, s.d. sie 
irgendetwas programmierer-definiertes tun; dann kann es schonmal sein 
dass man solche Ketten braucht.

von fibonacci de gogolores (Gast)


Lesenswert?

Kindergärtner schrieb:
> Nein, eine 5 ist nur ein temporärer Wert der gar nicht im Speicher
> landen muss, und hat daher auch keine Adresse.

Was passiert eigentlich mit einer Anweisung z.B. k=k+5 wird die 5 dazu 
erst in den Arbeitsspeicher geladen?

Kindergärtner schrieb:
>> Ich habe auch schon Dinge gesehen wie *&*k oder **&k was ist das dann?
> In C++ gibts da noch eine zusätzliche Gemeinheit, denn man kann den
> &-Operator und den *-Operator einer Klasse überladen, s.d. sie
> irgendetwas programmierer-definiertes tun; dann kann es schonmal sein
> dass man solche Ketten braucht.

War in diesem Fall C, als hatte nichts mit Operator überladen zu tun.
Leider finde ich gerade den Quelltext nicht in dem das vorkam.
Vielleicht weiß jemand so was diese Konstellation für eine Funktion hat.

von Kindergärtner (Gast)


Lesenswert?

fibonacci de gogolores schrieb:
> Was passiert eigentlich mit einer Anweisung z.B. k=k+5 wird die 5 dazu
> erst in den Arbeitsspeicher geladen?
Das hängt stark von der Plattform und vom Compiler ab. Auf 
Registermaschinen wie x86, AVR, ARM und mit optimierenden Compilern wie 
GCC kommt die 5 in ein temporäres Register oder gar nur direkt in die 
Instruktion (Programmcode).

> War in diesem Fall C, als hatte nichts mit Operator überladen zu tun.
> Leider finde ich gerade den Quelltext nicht in dem das vorkam.
> Vielleicht weiß jemand so was diese Konstellation für eine Funktion hat.
In C ist es lediglich unlesbarer sinnloser Code...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.