Forum: PC-Programmierung array kopieren in c


von Robert B. (rsb89)


Lesenswert?

Ich bin's schon wieder...

Folgendes Problem:
Ich möchte 5 Nachrichten speichern. Kommt eine neue Nachricht sollen die 
anderen durchgereicht werden, die letzte fällt raus.
1
uint8_t smstext[5][70];
2
static int i;
3
4
if(new_sms){
5
   for(i=3;i>=0;i--){
6
       memcpy(&smstext[i+1][0],&smstext[i][0],70);
7
   }
8
9
   SMS_Receive( new, &smstext[0][0] , 0 );
10
}

Also wenn eine SMS kommt soll zuerst die SMS aus smstext[3] in 
smstext[4] kopiert werden, dann 2 in 3, 1 in 2 und 0 in 1. Danach kann 
die neue SMS dann in 0 geschrieben werden. So habe ich mir das 
gedacht...

Was pasiert:
schicke ich "wer wie was" steht in smstext[0] auch "wer wie was". Hier 
müssten die anderen Arrays ja noch leer sein (Sind sie jedenfalls 
solange ich noch nichts empfangen habe). In smstext[1] steht dann aber 
"wer wie w" und in smstext[2] "wer". Die anderen beiden sind leer. Kann 
mir das jemand erklären?

von troll (Gast)


Lesenswert?

memcpy geht bei sich überlappenden Speicherbereichen nicht. memmove 
verwenden.

von Peter II (Gast)


Lesenswert?

troll schrieb:
> memcpy geht bei sich überlappenden Speicherbereichen nicht

hat er doch auch nicht.

von troll (Gast)


Lesenswert?

Peter II schrieb:
> troll schrieb:
>> memcpy geht bei sich überlappenden Speicherbereichen nicht
> hat er doch auch nicht.

Ok, zu schnell geguckt. Ich ziehe meine Aussage zurück und behaupte das 
Gegenteil. :-/

von Yalu X. (yalu) (Moderator)


Lesenswert?

Der Fehler befindet sich, wie so oft, nicht in dem geposteten
Code-Ausschnitt.

von Robert B. (rsb89)


Lesenswert?

Yalu X. schrieb:
> Der Fehler befindet sich, wie so oft, nicht in dem geposteten
> Code-Ausschnitt.

Gut dann weiss ich ja dass ich da nicht suchen brauch ;) Mehr Code 
kann/darf/will ich leider nicht posten. Trotzdem danke für die 
Bemühungen!

von D. I. (Gast)


Lesenswert?

Und was ist der Sinn dieser ständigen Umkopiererei? Sich einfach mit nem 
int + modulo die Position merken ist wohl zu einfach :)

von imon (Gast)


Lesenswert?

D. I. schrieb:
> Und was ist der Sinn dieser ständigen Umkopiererei? Sich einfach mit nem
> int + modulo die Position merken ist wohl zu einfach :)

Da kann ich mich nur anschließen, das Kopieren ist ziemlich "teuer"
nimm ein Ringbuffer (FIFO) ! Das scheint mir besser geignet. Index und 
modulo ist eine sehr effektive methode das zu Implementieren.

Wir haben hier auch ein artikel in welchen das erklärt wird.

http://www.mikrocontroller.net/articles/FIFO

von Robert (Gast)


Lesenswert?

Yalu X. schrieb:
> Der Fehler befindet sich, wie so oft, nicht in dem geposteten
> Code-Ausschnitt.

würd' ich auch sagen. Das SMS_Receive vermurkst/zerhackt/verpointert da 
irgendwas. Dein Fragment da sieht ansich jedenfalls funktionierend aus. 
Da das sicherlich zudem abstrahiert ist wird wohl kaum Hilfe möglich 
sein.

von heinz (Gast)


Lesenswert?

Zuerstmal sind die arrays nicht "leer", das hängt vom Compiler und 
dessen Einstellungen ab ob der die mit 0 initialisiert.

Zweitens weist Du aber schon das SMSe auch UTF-8 kodiert sein können? 
(bzw. irgend ein unicode)

Drittens [5] [70]      for(i=3;i>=0 ...

von D. I. (Gast)


Lesenswert?

heinz schrieb:
> Drittens [5] [70]      for(i=3;i>=0 ...

Wieso passt doch für sein Problem. 4 Durchläufe für 4 Kopiervorgänge.

von Vlad T. (vlad_tepesch)


Lesenswert?

R. B. schrieb:
> uint8_t smstext[5][70];
du weist schon, dass sms länger als 70 Zeichen sein können?
Info: wenn man Zeichen meint, sollte man char schreiben, meint man Bytes 
(Binärdaten) uint8_t

> static int i;
warum in alles in der Welt static?

>
> if(new_sms){
>    for(i=3;i>=0;i--){

>        memcpy(&smstext[i+1][0],&smstext[i][0],70);
man könnte auch strcpy nutzen
>    }
>
>    SMS_Receive( new, &smstext[0][0] , 0 );
> }

> uint8_t smstext[5][70];
> for(i=3;i>=0;i--){
> memcpy(&smstext[i+1][0],&smstext[i][0],70);
was ist denn, wenn du morgen 6 SMS mit 80 Zeichen Speichern willst?
Hast du schonmal was von Konstanten/defines gehört.
AUch würde ich für eine SMS eine Struktur anlegen, selbst wenn vorerst 
nur ein Char-Array drin steht, das macht diese ganze Indexgeschichte 
imho übersichtlicher und erspart das memcopy
1
#define SMS_MAX_TEXT_LENGTH 70
2
#define SMS_MAX_COUNT   5
3
typedef struct SMS
4
{
5
  char text[SMS_MAX_TEXT_LENGTH];
6
}SMS;
7
8
9
SMS sms[SMS_MAX_COUNT];
10
11
if(new_sms){
12
   int i;
13
   for(i=SMS_MAX_COUNT-1;i>=0;i--){
14
       sms[i+1] = sms[i];
15
   }
16
   SMS_Receive( new, &sms[0] , 0 );
17
}

so einfach kann Code aussehen.

Dass man hier mit einem Ringpuffer ganz auf das Kopieren ganz verzichten 
kann, erwähne ich nicht noch mal.

von Robert B. (rsb89)


Lesenswert?

> Da das sicherlich zudem abstrahiert ist wird wohl kaum Hilfe möglich
> sein.

Richtig! Es ist nur ein Ausschnitt und dann noch etwas abgeändert. 
Trotzdem danke für eure Bemühungen =) Es funkioniert jetzt, der Fehler 
lag wirklich woanders.

>Zweitens weist Du aber schon das SMSe auch UTF-8 kodiert sein können?

>du weist schon, dass sms länger als 70 Zeichen sein können?

Es geht nicht um die SMS die man vom Handy kennt. Das sind "meine" SMS 
da bestimme ich welche Kodierung die haben und wie lang die sind ;) Das 
mit der Konstanten für die Länge wird denke ich noch umgesetzt werden, 
danke für den Hinweis.

>Dass man hier mit einem Ringpuffer ganz auf das Kopieren ganz verzichten
>kann, erwähne ich nicht noch mal.

Ohne Worte...

von heinz (Gast)


Lesenswert?

@ D. I.
jup die i + 1 übersehen

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.