Forum: Compiler & IDEs Array kopieren / zuweisen


von Thomas (Gast)


Lesenswert?

Ich habe ein paar Codesequenzen vorgegeben und entscheide mich durch 
Eingabe verschiedener Tasten für einen der Codes. Dazu will ich das 
komplette Array in ein Arbeitsarray kopieren:

In Code:
1
static unsigned char code[] = {0,1,0,1};
2
static unsigned char arbeitsArray[4] = {};
3
if(codeNumber == 1)
4
{
5
arbeitsArray[] = code[]; // geht nicht: error: expected expression before ']' token
6
7
arbeitsArray = code; //geht leider auch nicht: error: incompatible types in assignment
8
}

wie schreibt man das richtig, oder kann man das so garnicht machen?

von Uhu U. (uhu)


Lesenswert?

memcpy(arbeitsArray,  code, sizeof arbeitsArray);

von Thomas (Gast)


Lesenswert?

also prinzipiell gehts natürlich auch via:
unsigned int i;
for(i=0; i<sizeof(code);i++)
{
arbeitsArray[i] = code[i];
}

aber gehts auch einfacher, also dass das Programm das nicht immer mühsam 
machen muss?
Pointer?

Prinzipiell gehts einfach darum, später mit dem ausgewählten Code 
weiterzuarbeiten, dafür ist das arbeitsArray, worauf ich dann alle 
möglichen operationen loslasse, das ursprüngliche array möchte ich nicht 
verändern wenn möglich.

von Thomas (Gast)


Lesenswert?

Danke Uhu Uhuhu. Warst schneller mitm schreiben als ich mitm abschicken 
des Nachtrags.

Wo findet man denn den Code zu memcpy()? Den Header hab ich dazu 
gefunden im WinAVR Verzeichnis. Also string.h, aber wo ist denn string.c 
? bzw. die eigentliche Implementierung?

von Uhu U. (uhu)


Lesenswert?

In der Runtimelibrary, wenn sie nicht vom Compiler als Intrinsic direkt 
eingebaut wird.

von Rolf Magnus (Gast)


Lesenswert?

> Wo findet man denn den Code zu memcpy()?

Wozu brauchst du den denn?

von Thomas (Gast)


Lesenswert?

Ich hätt ihn mir mal angesehn, ob vielleicht die forschleife drinsteht 
=) oder eben wie sies schlau gelöst hätten.

von Karl H. (kbuchegg)


Lesenswert?

Thomas wrote:
> Ich hätt ihn mir mal angesehn, ob vielleicht die forschleife drinsteht
> =) oder eben wie sies schlau gelöst hätten.

for Schleife ist durchaus möglich.

oft wird aber beim Umkopieren auf grössere Einheiten gewechselt
(2 Byte, 4 Byte, ...) um den Schleifen Overhead gegenüber der
Kopierleistung in einem Schleifendurchlauf zu verringern.

Dein Stichwort im Web lautet: Duff's device

von Thomas (Gast)


Lesenswert?


von Rolf Magnus (Gast)


Lesenswert?

Gerade so Sachen wie memcpy profitieren oft stark von Optimierungen. 
Daher ist es immer je nach Prozessor sehr unterschiedlich implementiert. 
So hat z.B. der x86 Stream-Befehle, die ein Kopieren eines ganzen 
Speicherblocks mit einer einzigen Assembleranweisung (+ Setup davor 
natürlich) durchführen können, aber alternativ läßt sich auch die SSE 
dazu verwenden, die den Vorteil hat, daß ein Register 128 Bit breit ist. 
Beim ARM gibt es die Möglichkeit, einen kleinen Speicherblock in mehrere 
Register auf einmal mit einer einzigen Instruktion zu laden und mit 
einer weiteren wieder rauszuschreiben. Andere Systeme können vielleicht 
sogar DMA dazu verwenden.
Oft hängt es auch noch von den Parametern ab (z.B. wenn die Größe des zu 
kopierenden Blocks eine Compilezeit-Konstante ist). Deshalb wird - wie 
schon angedeutet von Uhu - die Funktion (zumindest bei gcc) schon im 
Compiler selbst fest eingebaut, was ihm die besten 
Optimierungsmöglichkeiten gibt.

Die for-Schleife ist die einfachste Variante, die immer funktioniert, 
aber je nach Prozessor eben deutlich langsamer sein kann, als eine 
speziell zugeschnittene Version. Es kann aber umgekehrt sogar auch 
passieren, daß der Compiler den Zweck der Schleife erkennt und diese 
dann wieder durch einen memcpy-Aufruf ersetzt.

von Icke M. (Firma: my-solution) (hendi)


Lesenswert?

Ich hänge meine Frage mal hier an. Gibt es eine Möglichkeit einen Vektor 
anzulegen, bei dem man erst während der Laufzeit weiß wie groß er ist? 
Ich möchte die Daten meines Ethernetcontrollers auslesen, die sind aber 
natürlich immer unterschiedlich lang, je nach dem was ich sende. Oder 
muss ich mir dann während der Laufzeit Speicher allocieren?

von Falk B. (falk)


Lesenswert?

@ Icke Muster (Firma my-solution) (hendi)

>Ich hänge meine Frage mal hier an. Gibt es eine Möglichkeit einen Vektor
>anzulegen, bei dem man erst während der Laufzeit weiß wie groß er ist?

Nein.

>muss ich mir dann während der Laufzeit Speicher allocieren?

Ja.

MfG
Falk

von Simon K. (simon) Benutzerseite


Lesenswert?

Da ein EthernetPaket maximal ~1,5kB groß sein kann, kannst du auch fest 
1,5kB statisch allokieren.

von Icke M. (Firma: my-solution) (hendi)


Lesenswert?

Okay, ich hab mich falsch ausgedrückt, ich hätte gern die Nutzdaten, in 
dem Fall HTTP, zur weiteren Verwendung aneinanderhängend. Ich würde die 
also gern  aus den jeweiligen Päckchen extrahieren und dann weiter 
verwenden. vielleicht macht das auch keinen Sinn und ich sollte sie 
gleich parsen, aber ich hab halt Angst zwischendurch daten zu verlieren 
und würde gern alles, was gerade gesendet wurde erst mal speichern. Ich 
werd mir das einfach mal ansehen, irgendwann muss ich mich ja mal mit 
malloc beschäftigen, hätte es nur gern aufgeschoben...

von Uhu U. (uhu)


Lesenswert?

Wenn du C++ nimmst, kannst du eine Stringklasse verwenden, die die 
Speicherverwaltung im Hintergrund miterledigt.

Auf den üblichen µCs würde ich das aber nicht machen...

von Simon K. (simon) Benutzerseite


Lesenswert?

Icke Muster wrote:
> Okay, ich hab mich falsch ausgedrückt, ich hätte gern die Nutzdaten, in
> dem Fall HTTP, zur weiteren Verwendung aneinanderhängend. Ich würde die
> also gern  aus den jeweiligen Päckchen extrahieren und dann weiter
> verwenden. vielleicht macht das auch keinen Sinn und ich sollte sie
> gleich parsen, aber ich hab halt Angst zwischendurch daten zu verlieren
> und würde gern alles, was gerade gesendet wurde erst mal speichern. Ich
> werd mir das einfach mal ansehen, irgendwann muss ich mich ja mal mit
> malloc beschäftigen, hätte es nur gern aufgeschoben...

Der HTTP Teil eines TCP Pakets beginnt doch nach einem definierten 
Speicher-Offset. Da brauchst du nicht extra den Teil in einen anderen 
Speicher extrahieren. Das wäre zuviel des guten. Du gibst deiner 
HTTP-Funktion einfach einen Zeiger, der einen bestimmten Offset von der 
Start-Adresse des Ethernet-Buffers hat. (Den Offset muss man natürlich 
berechnen).

von Icke M. (Firma: my-solution) (hendi)


Lesenswert?

Das Problem ist, dass ich genau diesen Http Inhalt noch weiter verwenden 
möchte und wenn ich ein paar Daten mit POST z.B. übertrage, dann kommen 
die fragmentiert an und die würd ich gern zusammensetzen, oder ist das 
Quatsch? Ich dachte halt, das man danach einfacher damit arbeiten 
könnte, beim parsen.

von Simon K. (simon) Benutzerseite


Lesenswert?

Ok, das macht Sinn :-) Allerdings nur auf Controllern mit relativ viel 
Speicher...

Auf nem kleinen AVR 8-Bit würde ich auf sowas verzichten.

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.