Forum: Mikrocontroller und Digitale Elektronik C - Parameterübergabe


von Jan H. (janiiix3)


Lesenswert?

Hallo,

kann mir jemand sagen, was ich falsch mache?
Wenn ich den Parameter "id" in die übergebene Struktur kopieren möchte, 
klappt das nicht. Der Wert wird nicht gespeichert. Innerhalt der 
Funktion
"errorWrite" ist der Wert aber noch sichtbar. In der Funktion 
"checkBuff" nicht mehr?

In der Funktion "checkBuff" mache ich genau die gleiche Abfrage wie in 
"errorWrite".
1
typedef struct
2
{
3
  /*
4
  *  Fehlerspeicher
5
  */
6
  uint8_t buff[ERROR_BUFFER_ID_SIZE][ERROR_BUFFER_NUM_SIZE];
7
  
8
  /*
9
  *  Zähler für den "Zähler Typ"
10
  *  Wie viele verschiedene Fehler sind aufgetreten?
11
  *  
12
  *  z.B.: UART , LCD , I2C usw.
13
  */
14
  uint8_t typ;
15
  
16
  /*
17
  *  Zähler für aufgetretene Fehler
18
  */
19
  uint8_t err[ERROR_BUFFER_ID_SIZE][1];
20
  
21
}error_t;

1
uint8_t errorWrite( error_t *strc , uint8_t id , uint8_t err )
2
{
3
  uint8_t ret;
4
  
5
  /*
6
  *  Hier schlägt irgendwas fehl..
7
  *  id wird nicht in "strc->typ" kopiert?!
8
  */
9
  strc->typ = id;
10
  
11
  if( id > ERROR_BUFFER_ID_SIZE ) 
12
  {
13
    return 3;
14
  }
15
  
16
  ret = checkBuff( (error_t*)strc );
17
  
18
  if( ret > 1 )
19
  {
20
    return ret;
21
  }
22
  
23
  strc->buff[id][strc->err[id][0]++] = err;
24
25
  return 0;
26
}

von Dr. Sommer (Gast)


Lesenswert?

Jan H. schrieb:
> if( id > ERROR_BUFFER_ID_SIZE )
>   {
>     return 3;
>   }

Es muss >= sein.

Jan H. schrieb:
> strc->buff[id][strc->err[id][0]++] = err;

Hier tritt wahrscheinlich ein Buffer Overflow auf welcher den zuvor 
geschriebenen Wert überschreibt. Überprüft mal genau die Indices, nutze 
ggf. valgrind und -fsanitize=undefined .

von Helferchen (Gast)


Lesenswert?

Auf dem ersten Blick sollte die ID in die Struktur kopiert werden. Wie 
sieht der restliche Code aus? Welche Parameter übergibst du an 
errorWrite? Zeige auch mal bitte die Implementierung von checkBuff.

von Jan H. (janiiix3)


Lesenswert?

Helferchen schrieb:
> Auf dem ersten Blick sollte die ID in die Struktur kopiert werden.
> Wie
> sieht der restliche Code aus? Welche Parameter übergibst du an
> errorWrite? Zeige auch mal bitte die Implementierung von checkBuff.
1
static uint8_t checkBuff( error_t *strc )
2
{
3
  uint8_t index;
4
  for( index = 0 ; index < ERROR_BUFFER_ID_SIZE ; index++ )
5
  {
6
    if( strc->buff[index][0] != 'x' )
7
    {
8
      return 1; // Im Speicher sind Daten vorhanden!
9
    }
10
  }
11
  
12
  index = 0;
13
  for( index = 0 ; index < ERROR_BUFFER_ID_SIZE ; index++ )
14
  {
15
    if( strc->err[index][0] > ERROR_BUFFER_NUM_SIZE )
16
    {
17
      return 2; // Kein Platz mehr im Speicher!
18
    }
19
  }
20
21
  if( strc->id > ERROR_BUFFER_ID_SIZE )
22
  {
23
    return 3;
24
  }
25
26
  return 0; // Keine Daten vorhanden!
27
}

Hier wollte ich einfach mal testen ob die "returns" kommen. Das passiert 
aber nicht. Weil "id" nicht richtig an "checkBuff" übergeben wird.
1
  error_t err;
2
  for ( uint8_t i = 0 ; i < 30 ; i++ )
3
  {
4
    errorWrite( &err , i , i );
5
  }

von Markus F. (mfro)


Lesenswert?

Jan H. schrieb:
> strc->buff[id][strc->err[id][0]++] = err;

was hast Du dir dabei gedacht?

von Dr. Sommer (Gast)


Lesenswert?

Jan H. schrieb:
> if( strc->err[index][0] > ERROR_BUFFER_NUM_SIZE )

Jan H. schrieb:
> if( strc->id > ERROR_BUFFER_ID_SIZE )
>   {

Auch hier muss es wieder >= sein, sonst hilft das nix gegen Puffer 
Überläufe.

von Jan H. (janiiix3)


Lesenswert?

Es klappt mit ">=" auch nicht.
Hier mal das Programm (getestet mit DevC++)
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <stdint.h>
4
#include <string.h>
5
6
#define ERROR_BUFFER_ID_OVERFLOW  1
7
#define ERROR_BUFFER_NUM_OVERFLOW  2
8
9
#define  ERROR_BUFFER_ID_SIZE    10
10
#define ERROR_BUFFER_NUM_SIZE    4
11
12
typedef struct
13
{
14
  /*
15
  *  Fehlerspeicher
16
  */
17
  uint8_t buff[ERROR_BUFFER_ID_SIZE][ERROR_BUFFER_NUM_SIZE];
18
  
19
  /*
20
  *  Welche Art von Fehler ist aufgetreten?!
21
  *  
22
  *  z.B.: UART , LCD , I2C usw.
23
  */
24
  uint8_t id;
25
  
26
  /*
27
  *  Zähler für aufgetretene Fehler
28
  */
29
  uint8_t err[ERROR_BUFFER_ID_SIZE][1];
30
  
31
}error_t;
32
33
static uint8_t checkBuff( error_t *strc )
34
{
35
  uint8_t index;
36
  for( index = 0 ; index < ERROR_BUFFER_ID_SIZE ; index++ )
37
  {
38
    if( strc->buff[index][0] != 'x' )
39
    {
40
      return 1; // Im Speicher sind Daten vorhanden!
41
    }
42
  }
43
  
44
  index = 0;
45
  for( index = 0 ; index < ERROR_BUFFER_ID_SIZE ; index++ )
46
  {
47
    if( strc->err[index][0] > ERROR_BUFFER_NUM_SIZE )
48
    {
49
      return 2; // Kein Platz mehr im Speicher!
50
    }
51
  }
52
53
  if( strc->id >= ERROR_BUFFER_ID_SIZE )
54
  {
55
    return 3;
56
  }
57
58
  return 0; // Keine Daten vorhanden!
59
}
60
61
uint8_t errorInit( error_t *strc )
62
{
63
  uint8_t index;
64
  
65
  for( index = 0 ; index < ERROR_BUFFER_ID_SIZE ; index++ )
66
  {
67
    memset( strc->buff + index , 'x' , ERROR_BUFFER_NUM_SIZE );
68
    memset( strc->err  + index ,  0  , ERROR_BUFFER_NUM_SIZE );
69
  }
70
  
71
  return 0;
72
}
73
74
uint8_t errorWrite( error_t *strc , uint8_t id , uint8_t err )
75
{
76
  uint8_t ret;
77
  
78
  /*
79
  *  Hier schlägt irgendwas fehl..
80
  *  id wird nicht in "strc->typ" kopiert?!
81
  */
82
  strc->id = id;
83
  
84
  ret = checkBuff( (error_t*)strc );
85
  
86
  if( ret > 1 )
87
  {
88
    return ret;
89
  }
90
  
91
  strc->buff[id][strc->err[id][0]++] = err;
92
93
  return 0;
94
}
95
96
char *errorShowExist( error_t *strc )
97
{
98
  uint8_t indexTyp;
99
  uint8_t indexErr;
100
  char conv[2] = "";
101
  
102
  static char out[ ERROR_BUFFER_ID_SIZE * ERROR_BUFFER_NUM_SIZE] = "";
103
  
104
  for( indexTyp = 0 ; indexTyp < ERROR_BUFFER_ID_SIZE ; indexTyp++ )
105
  {
106
    if( strc->buff[indexTyp][0] != 'x' )
107
    {
108
      itoa( indexTyp , conv , 10 );
109
      strcat( out , conv );
110
      strcat( out , "#" );
111
      
112
      for( indexErr = 0 ; indexErr < strc->err[indexTyp][0] ; indexErr++ )
113
      {
114
        itoa( strc->buff[indexTyp][indexErr] , conv , 10 );
115
        
116
        strcat( out , conv );
117
        if ( strc->buff[indexTyp][indexErr+1] != 'x' )
118
        {
119
          strcat( out , "," );  
120
        }
121
        else
122
        {
123
          strcat( out , "\r\n");
124
        }
125
      }
126
    }
127
  }
128
  
129
  return out;
130
}
131
132
133
134
int main()
135
{  
136
  error_t err;
137
  errorInit( &err );
138
  
139
  uint8_t i = 0;
140
  
141
  for( ; i < 30 ; i++ )
142
  {
143
    printf( "%d" , errorWrite( &err , i , i ));
144
  }
145
  
146
    return 0 ;
147
}

von Jan H. (janiiix3)


Lesenswert?

Markus F. schrieb:
> Jan H. schrieb:
>> strc->buff[id][strc->err[id][0]++] = err;
>
> was hast Du dir dabei gedacht?
1
  /*
2
  * strc->err[id][0]++ = Damit werden die Fehler für die jeweilige ID gezählt
3
  */
4
  strc->buff[id][strc->err[id][0]++] = err;

von Markus F. (mfro)


Lesenswert?

dir ist schon klar, was das "++" da macht?

von Jan H. (janiiix3)


Lesenswert?

Markus F. schrieb:
> dir ist schon klar, was das "++" da macht?

Post-Inc.

von Jan H. (janiiix3)


Lesenswert?

Prüfe ich den Wert direkt am Anfang funktioniert es?!
1
static uint8_t checkBuff( error_t *strc )
2
{  
3
  uint8_t index;
4
  
5
  if( strc->id >= ERROR_BUFFER_ID_SIZE )
6
  {
7
    printf("Test");
8
    return 1; // ID kann nicht gespeichert werden!
9
  }
10
11
  for( index = 0 ; index < ERROR_BUFFER_ID_SIZE ; index++ )
12
  {
13
    if( strc->buff[index][0] != 'x' )
14
    {
15
      return 2; // Im Speicher sind Daten vorhanden!
16
    }
17
  }
18
  
19
  index = 0;
20
  for( index = 0 ; index < ERROR_BUFFER_ID_SIZE ; index++ )
21
  {
22
    if( strc->err[index][0] > ERROR_BUFFER_NUM_SIZE )
23
    {
24
      return 3; // Kein Platz mehr im Speicher!
25
    }
26
  }
27
28
  return 0; // Keine Daten vorhanden!
29
}

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Jan H. schrieb:
> #define  ERROR_BUFFER_ID_SIZE    10

Okay, wir haben 10 IDs.

>   uint8_t err[ERROR_BUFFER_ID_SIZE][1];

Damit haben wir hier err[10][1].

>   strc->buff[id][strc->err[id][0]++] = err;

Hier wird auf err[id] zugegriffen.
1
>   for( ; i < 30 ; i++ )
2
>   {
3
>     printf( "%d" , errorWrite( &err , i , i ));
4
>   }

Hier läuft i bis 29.

Also bereits bei i = 10 gibts einen Buffer-Overflow.

Lasse ich die for-Schleife bis 9 laufen, klappts natürlich:
1
   for( ; i < ERROR_BUFFER_ID_SIZE; i++ )
2
   {
3
     printf( "%d" , errorWrite( &err , i , i ));
4
   }
1
>  /*
2
>  *  Hier schlägt irgendwas fehl..
3
>  *  id wird nicht in "strc->typ" kopiert?!
4
>  */
5
>  strc->id = id;

Nein, das ist nur ein Folgefehler.

Hättest Du Dir mal id aus dem Ausdruck strc->err[id][0]++ ausgeben 
lassen, wäre Dir schnell aufgegangen, dass hier was in die Hose geht.

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.