Arraysübergabe

hallo,
kann mir da jemand vielleicht sagen warum die Arraysübergabe nicht klappt, obwohl ich es immer auf diese Weise erfolgreich übergeben bekommte.

 byte* RFID::Print_Block() {
  if (arrayfull == true) {
    static unsigned char BlockData[4];
     Serial.println("first print");
    for (int i=5; i<9; i++){
      BlockData[i]=printArray[i];
      Serial.println(BlockData[i], HEX);
    }
      pruef = true;
      arrayfull = false;     
      return BlockData;
  }
  else if (NovalidArray == true ) {
    NovalidArray = false;
    return -2;
    }
    else return -4;
}

int RFID::pruefung(){
  if (pruef == true){
    Serial.println("second print");
    unsigned char *a;
    unsigned char Block[4];
    a=Print_Block(); 
    for (int i=0; i<4; i++){
       Block[i]=*(a+i);
       Serial.println(Block[i], HEX); 
  }
  pruef= false;
  }
 }

Die Ausgabe

⸮aah⸮first print
AA
B
B
68
second print
49
AC
D5
75
⸮aah╪aah⸮first print
AA
B
B
68
second print
49
AC
D5
75
⸮aah╪aah

Wenn ich das richtig sehe, definierst Du dir in der ersten Funktion ein Array BlockData[4] mit also 4 Elementen. In der darauffolgenden for-Schleife schreibst Du aber ab Index 5 hinein. D.h. Du schreibst in irgendwas, was im Speicher hinter deinem BlockData liegt.

ich nehme halt die Werte aus einem anderen Array (printarray[]), und es sind genau die Stellen die ich brauche.

ich habe mal ein Debug hinzugefügt ,um zu das Array unmittelbar nach der Deklarierung zu vergleichen.
komischerweise hat es sich die Werte eines Telegramm geholt, die ich meinem Sensor gesendet hatte.

int RFID::pruefung(){
  if (pruef == true){
    Serial.println("second print");
    int *a;
    unsigned char Block[7];
    for (int i=0; i<7; i++){
       Serial.println(Block[i], HEX); 
  }
    a=Print_Block(); 
    Serial.println("second print");
    for (int i=0; i<4; i++){
       Block[i]=*(a+i);
       Serial.println(Block[i], HEX); 
  }
  pruef= false;
  }
 }

debug

⸮aah⸮first print
0
0
0
0
second print
AA
7
7
68
8
E2
95
second print
49
D5
FC
8
⸮aah╪aah

pispa:
ich nehme halt die Werte aus einem anderen Array (printarray[]), und es sind genau die Stellen die ich brauche.

Fürs Lesen mag das ja in Ordnung sein ( ich weiß nicht, wie dein printarray definiert ist ). Aber fürs Schreiben in dein BlockData kannst Du dann nicht den gleichen Index nehmen. So wie Du das definiert hast, sind nur 0..3 als Index erlaubt. Und Du liest ja auch hinterher ab Index 0. Dann musst Du auch ab Index 0 hineinschreiben.

pispa:
ich habe mal ein Debug hinzugefügt ,um zu das Array unmittelbar nach der Deklarierung zu vergleichen.

Dein Array 'Block' legst Du dynamisch auf dem Stack an. Was da drin steht, bevor Du selbst was reingeschrieben hast ist reiner Zufall.

MicroBahner:
Fürs Lesen mag das ja in Ordnung sein ( ich weiß nicht, wie dein printarray definiert ist ). Aber fürs Schreiben in dein BlockData kannst Du dann nicht den gleichen Index nehmen. So wie Du das definiert hast, sind nur 0..3 als Index erlaubt. Und Du liest ja auch hinterher ab Index 0. Dann musst Du auch ab Index 0 hineinschreiben.

ich habe das mal anders gemacht, sodass ich nichts mehr reinschreiben muss. es hilft immer noch nicht.

es hilft immer noch nicht.

Sollen wir helfen oder reicht Mitleid?

(Wie) hast du die bisher aufgezeigten Fehler korrigiert?

dieser Teil ist jetzt weggelassen worden

 static unsigned char BlockData[4];
     Serial.println("first print");
    for (int i=5; i<9; i++){
      BlockData[i]=printArray[i];
      Serial.println(BlockData[i], HEX);
    }

Einfach weglassen hilft doch nicht. Was gibst Du denn dann als Array-Pointer zurück?
Das wäre z.B. eine Möglichkeit:

for (int i=5; i<9; i++){
      BlockData[i-5]=printArray[i]; // <--in BlockData mit einem negativen Offset
                                    // reinschreiben, so dass es da ab 0 losgeht
      Serial.println(BlockData[i], HEX);
    }

Natürlich würde es auch andersrum gehen: For-Schleife ab 0, und für printArray einen positiven Offset verwenden

Und was ist aus

return BlockData;

geworden?
Ausserdem fehlt deine Test-Umgebung
setup, loop , globale Variable
Vielleicht findest du deinen Fehler sogar selbst, wenn du ein Beispiel (minimal aber komplett) zusammenstellst, das nur dazu dient, das Problem zu zeigen.

Was mir ganz unsauber aufstößt, ist das statische Array in einer Methode.

static unsigned char BlockData[4];

Aus meiner Sicht hat sowas zu viele unangenehme Seiteneffekte.

ich brauche eigentlich nicht mehr Blockdata[], ich gebe jetzt direkt das Array PrintArray[], von dem
Blockdata[] seine Elemente bezug.

hier nochmal die Änderung

byte* RFID::Print_Block() {
  if (arrayfull == true) {
     Serial.println("first print");                     //->das hier dient
    for (int i=5; i<9; i++){                          //-> nur dem 
     Serial.println(printArray[i], HEX);          //->Anzeigen
    }
      pruef = true;
      arrayfull = false;     
      return printArray;                              // Hier gebe ich Printarray zurück und nicht Blockdata
  }
  else if (NovalidArray == true ) {
    NovalidArray = false;
    return -2;
    }
    else return -4;
}

michael_x:
Und was ist aus

return BlockData;

geworden?
Ausserdem fehlt deine Test-Umgebung
setup, loop , globale Variable
Vielleicht findest du deinen Fehler sogar selbst, wenn du ein Beispiel (minimal aber komplett) zusammenstellst, das nur dazu dient, das Problem zu zeigen.

BlockData war überflüssig.
das ist die minimierte Version, um den Fehler zu finden :slight_smile:

Aus meiner Sicht hat sowas zu viele unangenehme Seiteneffekte

Das sind hier aber eher philosophische Fragen. In der einfachen single-thread Arduino-Welt geht das schon.

Beim aktuellen Stand der Frage hier "Array Übergabe" kann pispa mit oder ohne static array zum Ziel kommen.

Meine Antwort auf

kann mir da jemand vielleicht sagen warum die Arraysübergabe nicht klappt

wäre: ich sehe gar keine Arrayübergabe. Und wenn ich rate, was ohne das überflüssige BlockData da steht, erst recht nicht mehr.

ich benutze halt dieses Array ausserhalb der Bibliothek, deswegen soll es aus der Funktion zurückgegeben werden. das Unterprogramm Pruefung dient eigentlich nur zum Testen.
so möchte mein Programm eigentlich verwenden
in der cpp Datei

byte* RFID::Print_Block() {
  if (arrayfull == true) {
     Serial.println("first print");
    for (int i=5; i<9; i++){
     Serial.println(printArray[i], HEX);
    }
      arrayfull = false;     
      return printArray;
  }
  else if (NovalidArray == true ) {
    NovalidArray = false;
    return -2;
    }
    else return -4;
}

in meinem Sketch

#include <LiquidCrystal.h>                                
#include"RFID.h"
RFID  RFID(6); // Initialisieren der Bibliothek mit der Send_recievepin Nummer 6
LiquidCrystal lcd(12, 11, 5, 4, 3, 7); 
void setup() {
    lcd.begin(16,2); 
  }

void loop() {
    RFID.Read_Block();
    delay(1);
    PrintBlocks();
}

void PrintBlocks(){
  int Pruefbyte;
  Pruefbyte=RFID.Print_Block();
  if (Pruefbyte==(-4))
    return NULL;
  else{
    lcd.setCursor(0,0);
   unsigned char *p;
    unsigned char Block[4];
    p=RFID.Print_Block();
   Serial.println("second print");
    for (int i=0; i<4; i++){
       Block[i]=*(p+i);
     Serial.println(Block[i], HEX); 
       lcd.print(Block[i], HEX);
  }
 }
}

und Das Debuging

⸮aah╪aah⸮first print
0
0
0
0
second print
49
AC
D5
75
⸮aah╪aah

Das sind hier aber eher philosophische Fragen.

OK, mag sein, vielleicht ist das eine Philosophie...

Aber spätestens, wenn der Dolch im Rücken steckt, könnte man daran denken, dass so manche Philosophie schon zu praktischer Anwendung gekommen ist.

So wie die anfängliche Array Bereichsüberschreitung.
Auch so ein Dolch.

Und hier noch:
(nur auf den Irrtum reduziert)

byte* RFID::Print_Block() {
     return printArray;                 
     return -2;
     return -4;
}

Alle meine Nackenhärchen stellen sich dabei auf.

Insgesamt (aus meiner Sicht) 3 fette Böcke (NoGos) in ca 20 Zeilen Code

Ja, hier könnte eine etwas weiter entwickelte Philosophie durchaus positive Wirkung zeigen.

   return -2;
    }
    else return -4;

Dein Rückgabewert ist byte*. Da passt was nicht

Und in der anderen Funktion verwendest du dann diese Fantasiewerte als ob es echte Zeiger wären. Irgendwie hast du da nicht verstanden was Zeiger sind

Auch hier:

void PrintBlocks()
{
   ....
   return NULL;

??

combie:
OK, mag sein, vielleicht ist das eine Philosophie...

Aber spätestens, wenn der Dolch im Rücken steckt, könnte man daran denken, dass so manche Philosophie schon zu praktischer Anwendung gekommen ist.

So wie die anfängliche Array Bereichsüberschreitung.
Auch so ein Dolch.

Und hier noch:
(nur auf den Irrtum reduziert)

byte* RFID::Print_Block() {

return printArray;               
    return -2;
    return -4;
}



Alle meine Nackenhärchen stellen sich dabei auf.


Insgesamt (aus meiner Sicht) 3 fette Böcke (NoGos) in ca 20 Zeilen Code

Ja, hier könnte eine etwas weiter entwickelte Philosophie Wirkung zeigen.

du könntest mir einfach verraten wie ich den beheben soll.
es kann ja sein, dass mein Wissen zu dem Thema nicht so breit ist und die Fehler, die du findest , für mich nicht offensichtlich sind.

void PrintBlocks(){
  int Pruefbyte;
  Pruefbyte=RFID.Print_Block();
  if (Pruefbyte==(-4))
    return NULL;

Auch der Abschnitt ist eher seltsam.

void und return NULL passen nicht gut zusammen.

Auch Pruefbyte==(-4) erscheint mir sehr seltsam.
In meiner bescheidenen Weltsicht, kann ein Byte niemals negative Werte annehmen.

Das sind hier aber eher philosophische Fragen.

:o :o :o
Ja, vielleicht......

du könntest mir einfach verraten wie ich den beheben soll.
es kann ja sein, dass mein Wissen zu dem Thema nicht so breit ist und die Fehler, die du findest , für mich nicht offensichtlich sind.

Nein, kann ich nicht!

Bisher zeigst du nur untestbare Fragmente.
Auch liegt das Gesamtkonzept noch im dunklen.

byte* RFID::Print_Block() {

return printArray;               
    return -2;
    return -4;



}

Hier sagt die Filosofie ganz klar:
Ein Pointer ist ein Pointer und muss ein Pointer bleiben.
Man darf ihn NULL setzen, oder nullptr, aber nicht auf -2 oder -4.
Es sei denn, man hat extrem gute Gründe dafür.
z.B. Absolute Hardware Adressierung, aber dafür fehlt dann noch das volatile.

byte* RFID::Print_Block() {
     return printArray;                 
     return (byte*)-2;
     return (byte*)-4;

... und später wundern was man denn damit ausdrücken wollte ...

Das unterdrückt vielleicht Warnungen (wenn sie denn überhaupt aktiviert sind), aber ist immer noch sinnlos. Zeiger sind Adressen. Was ist eine negative Adresse? Da wird sowieso ein Überlauf/Unterlauf statt finden