Tag 14 – Letzte Farbe anzeigen

Forums (Deutsch) Adventskalender Tag 14 – Letzte Farbe anzeigen

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #865
    Klaus
    Participant

    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?

    #868
    Raabinator
    Member

    Also, 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.

    • This reply was modified 8 years, 4 months ago by Raabinator.
    Attachments:
    #872
    Klaus
    Participant

    OK, 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.

    #879
    Raabinator
    Member

    Hallo 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 also sizeof()-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 das array[sizeof(array)]-Byte. Da an dieser Stelle im Speicher zufällig eine 0 steht -> die dritte 0.

    • This reply was modified 8 years, 4 months ago by Raabinator.
    • This reply was modified 8 years, 4 months ago by Raabinator.
    • This reply was modified 8 years, 4 months ago by Raabinator.
    #883
    Klaus
    Participant

    Das 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.

Viewing 5 posts - 1 through 5 (of 5 total)
  • You must be logged in to reply to this topic.