C - Parameterübergabe

OP #5436414
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
}
Gast #5436419
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.
OP #5436423
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
  }
OP #5436431
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
}
OP #5436462
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
}
Moderator Persönliche Seite #5436520
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.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.