Tag 14 – Letzte Farbe anzeigen
› Foren › Adventskalender › Tag 14 – Letzte Farbe anzeigen
- Dieses Thema hat 4 Antworten und 2 Teilnehmer, und wurde zuletzt aktualisiert vor 8 Jahren, 9 Monaten von Klaus.
-
AutorBeiträge
-
Dezember 14, 2015 um 18:37 Uhr #865KlausTeilnehmer
Hallo zusammen,
ich hab mal wieder etwas gebastelt und bis dabei gleich noch auf einen Fehler im Programm gestoßen.
Meine Version zeigt nun die zuletzt gewählte Farbe im Colorpicker an.Dabei kamen immer wieder Zeichen zum Browser, die ich gar nicht im Quellcode habe. Dann habe ich festgestellt, dass im PROGMEM noch mehr Zeichen stehen, als man sieht. Deshalb darf die Schleife nicht
for (int i = 0; i <= sizeof(site); i++)
sondern
for (int i = 0; i < sizeof(site)-1; i++)
heißen, da 2 Zeichen zu viel aus dem Speicher gelesen werden. Eines wäre mir ja noch klar, wenn es nur das Nullbyte wäre. Aber warum 2? Kennt jemand den Grund dafür?Attachments:
Dezember 14, 2015 um 19:41 Uhr #868RaabinatorMitgliedAlso, bei mir hängen drei Nullen dran (siehe Bild)
- Die erste ist die Null im String, die mit
/0
erzeugt wird (ist unnötig) - Die zweite Null ist die, die der Compiler automatisch an die Zeichenkette anhängt (site ist eins Größer als Zeichen angegeben sind)
- Die dritte Null ist das was zufällig als nächstes im Programmspeicher kommt. Leider gibt die Arduino-IDE kein .map-File aus. Dort könnte man nachsehen, was als nächstes kommt.
Um das komplette Array zu senden (inkl. der automatischen Ende-Null) sollte die Schleife so aussehen:
for (int i = 0; i < sizeof(site); i++)
Da wir aber eine Zeichenkette senden könnten wir auch die Null als Ende verwenden, dann so:
int i = 0; while (meinArray[i] != '\0') { // ... mach was mit dem Zeichen ... i++; }
Das wird aber unübersichtlich, da wir das Zeichen erst mit der Funktion
pgm_read_byte_near
aus dem Flash lesen müssen.Im Sketch des Autors wird der String durch das
<=
um ein Zeichen überlesen. Richtig wäre<
. Damit wird auch die Ende-Null gesendet, die der Browser aber nicht braucht. Daher ganz richtig mit< sizeof(site)-1
.- Diese Antwort wurde geändert vor 8 Jahren, 9 Monaten von Raabinator.
Attachments:
Dezember 15, 2015 um 08:30 Uhr #872KlausTeilnehmerOK, die ersten beiden leuchten mir ja jetzt ein. Aber warum sendet er dann noch ein drittes Byte zu viel?
Das mit< sizeof(site)
leuchtet ja auch ein, wenn man mal drüber nachdenkt. Man fängt bei 0 an. Die Größe fängt natürlich bei 1 an. Deshalb muss man ja 1 früher aufhören. Aber wie kommt es dann zustande, dass er trotzdem 1 übers Ende raus liest?
Btw, bei mir liest er anscheinend nur 2 Bytes zu viel, was anhand der Erklärung automatisch \0 dran hängen und Größe fängt bei 0 an, auch logisch ist.
Ich müsste mal den Sniffer anwerfen, um zu sehen, was er genau sendet. Oder ob das dritte Byte bei mir nur nicht zu sehen ist.Dezember 16, 2015 um 09:57 Uhr #879RaabinatorMitgliedHallo Klaus
Das kann man mit Wireshark gut beobachten (http://www.wireshark.org).
sizeof()
gibt die Größe des Array zurück. Die Indizierung des ersten Elementes beginnt bei 0, das letzte Element ist damit alsosizeof()-1
.
Um alle Elemente zu indizieren müsste die Schleife bis<= sizeof()-1
oder gleichbedeutend< sizeof()
laufen. Dies beinhaltet dann die 0 in der Zeichenkette und die automatische 0, die auch in die Größe mit eingerechnet ist.
Mit<= sizeof()
wird nochmal ein Byte mehr gelesen (durch das=
), nämlich dasarray[sizeof(array)]
-Byte. Da an dieser Stelle im Speicher zufällig eine 0 steht -> die dritte 0.- Diese Antwort wurde geändert vor 8 Jahren, 9 Monaten von Raabinator.
- Diese Antwort wurde geändert vor 8 Jahren, 9 Monaten von Raabinator.
- Diese Antwort wurde geändert vor 8 Jahren, 9 Monaten von Raabinator.
Dezember 16, 2015 um 10:37 Uhr #883KlausTeilnehmerDas ist mir schon klar, hatte ich ja oben auch geschrieben. Aber bei meinen Versuchen hatte er noch ein drittes Byte zu viel. Allerdings gestern war das nicht so. Keine Ahnung, was da noch los war. Funktioniert aber inzwischen.
-
AutorBeiträge
- Du musst angemeldet sein, um auf dieses Thema antworten zu können.