Forum: Compiler & IDEs Overflow bei pointer in structure


von Hans (Gast)


Lesenswert?

Hallo,

ich will in einem Structure die letzten 7 Mittelwerte der jeweiligen 
Sensoren auslesen und den höchsten Wert erhalten. Jedoch liefert unten 
angeführtes Beispiel immer die falschen Werte. Wie muss ich den COde 
ändern, damit er funktioniert? Kann man ihn mittels Pointer auch etwas 
effizienter machen? (kenn mich da noch nicht so gut aus)

Grüße Hans
1
typedef struct {
2
        uint8_t param;
3
  uint16_t Mittelwerte[30];    //Minutenmittelwerte
4
}sensor;
5
6
sensor sensoren[12];
7
uint8_t index;
8
9
void Evaluation(void)
10
{
11
    uint8_t i,j, ptr*;
12
    uint8_t highVal;
13
14
    for(i = 0; i < 12; i++)
15
    {
16
        for(j=0;j<8;j++)
17
        {
18
             if(sensoren[i].Mittelwert[index-j]>highVal)
19
                  highVal=sensoren[i].Mittelwert[index-j];
20
        }
21
    }
22
23
  vPutnLCD(highval);
24
}

von yalu (Gast)


Lesenswert?

highval muss am Anfang auf den kleinstmöglichen Wert initialisiert
werden.

for(j=0;j<8;j++) berücksicht die letzten 8, nicht die letzten 7
Mittelwerte.

Wo kommt der Wert für index her?

von yalu (Gast)


Lesenswert?

> highval muss am Anfang auf den kleinstmöglichen Wert initialisiert
> werden.

... also 0, da die Mittelwerte unsigned sind.

Wenn die Mittelwerte 16 Bits breit sind, sollte dies auch highVal
sein.

von Hans (Gast)


Lesenswert?

Danke für die Hilfe,

aber es hapert immer noch irgendwo. Mit Hilfe von "index" werden die 
alten Werte in einer anderen Funktion  überschrieben. Anschließend wird 
der index dort auch um 1 erhöht. So, hab mal ausgebessert:
1
typedef struct {
2
        uint8_t param;
3
        uint16_t Mittelwerte[30];    //Minutenmittelwerte
4
}sensor;
5
6
sensor sensoren[12];
7
uint8_t index;
8
9
void Evaluation(void)
10
{
11
    uint8_t i,j, ptr*;
12
    uint16_t highVal=0;
13
14
    for(i = 0; i < 12; i++)
15
    {
16
        for(j=0;j<7;j++)
17
        {
18
             if(sensoren[i].Mittelwert[index-j]>highVal)
19
                  highVal=sensoren[i].Mittelwert[index-j];
20
        }
21
    }
22
23
  vPutnLCD(highval);
24
}

von Karl H. (kbuchegg)


Lesenswert?

Hans wrote:
> Danke für die Hilfe,
>
> aber es hapert immer noch irgendwo.

Was heist das genau?

In deiner Funktion ist ansonsten so nichts mehr zu sehen.
Solange index einen Wert groesser/gleich 6 hat und
die Werte auch richtig im Array abgelegt sind, muss das
funktionieren.

von Hans (Gast)


Lesenswert?

Hier noch die Funktion zum Aktualisieren der Messwerte. (Wird jede Sek. 
aufgerufen)
1
void Refresh(void)
2
{
3
     uint16_t values[12]   
4
     getMeasurements(values);
5
6
     for(i = 0; i < 12; i++)
7
          sensoren[i].Mittelwert[index]=values[i];         
8
    
9
    if(index>=29)
10
       index=0;
11
    else
12
       index++;
13
}

von Karl H. (kbuchegg)


Lesenswert?

Hans wrote:
>     if(index>=29)
>        index=0;


Ööhm.
Wenn index den Wert 0 hat, was ergibt dann index - j.
Dieser Ausdruck kommt in deiner Ermittlungsfunktion vor
und j nimmt innerhalb der Schleife Werte zwischen 0 und 6
an.
Wenn also index gleich 0 ist und j schon auf den Wert 6
vorgerückt ist, dann wird 0 - 6 zu -6. Und ein Array
Element mit dem Index -6 wirst du in keinem Array finden.

von Hans (Gast)


Lesenswert?

Ah, danke!

Wenn ich einen Pointer auf die Mittelwerte setze und dann den Pointer 
andauernd inkrementiere, läuft dieser dann im Kreis (springt nach dem 
letzten wieder zum Ersten), oder zeigt er dann ins Nirvana?

von Karl H. (kbuchegg)


Lesenswert?

Hans wrote:
> Ah, danke!
>
> Wenn ich einen Pointer auf die Mittelwerte setze und dann den Pointer
> andauernd inkrementiere, läuft dieser dann im Kreis (springt nach dem
> letzten wieder zum Ersten),

Nein.
Warum sollte er?

> oder zeigt er dann ins Nirvana?

Jep. Aber vergiss Pointer. Die bringen dich hier auch nicht
weiter.

Du musst deine Aufgabenstellung neu durchdenken. Vor allen
Dingen was du machen willst wenn weniger als 7 Mittelwerte
vorhanden sind und du aber den größten Mittelwert von 7
auf Biegen und Brechen bestimmen willst. Das kann dich
dann zur Lösung für dein jetziges Problem führen.

von Hans (Gast)


Lesenswert?

So? oder gehts noch einfacher?
1
void Evaluation(void)
2
{
3
    uint8_t i,j, ptr*;
4
    uint16_t highVal=0;
5
6
    for(i = 0; i < 12; i++)
7
    {
8
        for(j=0;j<7;j++)
9
        {
10
             if(index>j)
11
             {
12
                 if(sensoren[i].Mittelwert[index-j-1]>highVal)
13
                     highVal=sensoren[i].Mittelwert[index-j];
14
             }
15
             else
16
             {
17
                  if(sensoren[i].Mittelwert[29+index-j]>highVal)
18
                      highVal=sensoren[i].Mittelwert[index-j];
19
             }
20
        }
21
    }
22
23
  vPutnLCD(highval);
24
}

von Karl H. (kbuchegg)


Lesenswert?

Hans wrote:
> So? oder gehts noch einfacher?

Was heist einfacher.
Erst mal sollte es richtig sein :-)

Vergleichst du
>                  if(sensoren[i].Mittelwert[index-j-1]>highVal)
                                  hier:      *********
>                      highVal=sensoren[i].Mittelwert[index-j];
                                  mit:                *******
>              }
>              else
>              {
>                   if(sensoren[i].Mittelwert[29+index-j]>highVal)
            und nochmal                hier:  **********

>                       highVal=sensoren[i].Mittelwert[index-j];
                                       mit:            *******

Das wird wohl nichts werden, wenn du ein ganz anderes Element
zum vergleich benutzt, als das von dem dann die Zuweisung
ausgeht.

Was lernen wir daraus?
Kommt eine 'komplexe' Berechnung mehrmals in einem Codestück
vor, dann lohnt es sich immer, dafür eine Variable abzustellen
und die Berechnung zuerst mal nur einmal zu machen und das Ergebnis
in dieser Variablen zuwischenzuspeichern. In Folge wird dann anstelle
der Berechnung die Variable benutzt.

Was lernen wir noch daraus?
Das Code bei dem allesineinerWurschtgeschriebenwird nicht gerade
die Übersichtlichkeit fördert. Ein paar Leerzeichen an strategischen
Stellen positioniert können den Unterschied ausmachen zwischen
einem Code der fehlerhaft ist und einem Code bei dem einem
die Fehler nur so in die Augen springen. Ein paar Leerzeichen
hie und da dauern weder länger zum tippen noch bekommt man
Ausschlag davon.
1
void Evaluation()
2
{
3
    uint8_t  i, j;
4
    uint16_t highVal=0;
5
    uint8_t  testIndex;
6
7
    for( i = 0; i < 12; i++ )
8
    {
9
        for( j = 0; j < 7; j++ )
10
        {
11
            testIndex = index - j;
12
            if( index < j )
13
                testIndex += 30;
14
  
15
            if( sensoren[ i ].Mittelwert[ testIndex ] > highVal )
16
                highVal = sensoren[ i ].Mittelwert[ testIndex ];
17
        }
18
    }
19
20
    vPutnLCD( highval );
21
}

von Hans (Gast)


Lesenswert?

Danke sehr für die Tipps und Ratschläge ;-)

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.