Forum: Compiler & IDEs Problem mit Zeigern auf Structe


von Philipp M. (lord-maricek)


Angehängte Dateien:

Lesenswert?

Moin,

in meim Autopilotprogramm an dem ich zurzeit schreibe habe ich ein 
kleines Porblem. Der Code ist im Anhang. Ich hoffe, dass ihr da 
einigermaßen durchsteigt. Kurze erklärung dazu.
In dem Programm habe ich mehrere Strcte mit jeweils mehreren Instanzen.
Jede Instanz wird mit einer Init Funktion für ihr aufgaben zurecht 
gemacht.
Protocol Struct.
1
typedef struct protocol{
2
    unsigned char check_byte[100];
3
    unsigned char data[100];
4
    unsigned char mode;
5
    struct protocol *forward;
6
    autopilot *navi;
7
}protocol;
Es gibts 3 Instanzen:
Ankommende Daten (in_data), Ausgehende Daten (out_data), und Daten die 
weitergeleitet werden müssen (forward_data).
In der Initfunktion für in_data, ein Zeiger auf die Instanz von 
forward_data übergeben, dass Daten aus dem Struct in_data innerhalb des 
Programms in die Instanz von forwrd_data geschrieben werden können. Das 
funktioniert auch.

Bei dem Autopilot Struct geht das auch alles ohne Probleme.

Ich bin dabei, einen NMEA Parser zu schreiben. Damit die Daten nachdem 
"herrausschneiden" weiterverarbeitet werden, werden sie per Zeiger an 
den Autopiloten und als 4 stelliges Array an out_data übergeben. Aber 
genau diese beiden Sachen gehen nicht, obwohl ich alles genauso mache, 
wie bei den Funktionen davor.

Hier werden die zeiger auf die Instanzen in das Struct geschrieben.
1
void gps_init(gps * const _this,protocol * const pr, autopilot * const ap,char sentence[5])
2
{
3
    _this->p_out = pr;
4
    _this->ap = ap;
5
    for(unsigned char i=0; i<5; i++)
6
    {
7
        _this->sentence[i] = sentence[i];
8
    }
9
}

In der Main funktion:
1
gps gps_info;
2
3
int main(void)
4
{
5
  sei();
6
  fifo_init(&xbee_in,xbee_in_buffer,BUFFER_SIZE);
7
  fifo_init(&xbee_out,xbee_out_buffer,BUFFER_SIZE);
8
  fifo_init(&gps_fifo,gps_fifo_buffer,BUFFER_SIZE);
9
  
10
  protocol_init_in(&in_data,&forward_data,&ap);
11
  protocol_init_forward(&forward_data,&ap);
12
  protocol_init_out(&out_data,&ap);
13
  
14
  gps_init(&gps_info,&out_data,&ap,"GPRMC");     <=========
15
        usw...

Das Struct, in denen die zeiger gespeichert werdne sollten:
1
typedef struct {
2
    protocol * p_out;
3
    autopilot * ap;
4
    unsigned char sentence[5];
5
    unsigned char buffer[255];
6
    unsigned char indexer;
7
    unsigned char end_char_counter;
8
  unsigned char validation_status;
9
  unsigned char new_validation_status;
10
}gps;

Und die Funktion, in der das ganze weitergeleitet werden soll:
1
void set_gps_positon(gps * const _this,double lon,double lat)
2
{
3
  _this->ap->lon = lon;
4
  _this->ap->lat = lat;
5
  
6
  unsigned char out_lon[4];
7
    unsigned char out_lat[4];
8
9
    out_lon[3] = floor(((lon/0.0001)-(floor((lon/0.0001))))/0.01);
10
    out_lon[2] = floor(((lon/0.01)-(floor((lon/0.01))))/0.01);
11
    out_lon[1] = floor((lon-floor(lon))/0.01);
12
    out_lon[0] = floor(lon);
13
14
    out_lat[3] = floor(((lat/0.0001)-(floor((lat/0.0001))))/0.01);
15
    out_lat[2] = floor(((lat/0.01)-(floor((lat/0.01))))/0.01);
16
    out_lat[1] = floor((lat-floor(lat))/0.01);
17
    out_lat[0] = floor(lat);
18
  
19
  _this->p_out->data[NEW_WAYPOINT_LON4] = out_lon[3];
20
    _this->p_out->data[NEW_WAYPOINT_LON3] = out_lon[2];
21
    _this->p_out->data[NEW_WAYPOINT_LON2] = out_lon[1];
22
    _this->p_out->data[NEW_WAYPOINT_LON1] = out_lon[0];
23
24
    _this->p_out->data[NEW_WAYPOINT_LAT4] = out_lat[3];
25
    _this->p_out->data[NEW_WAYPOINT_LAT3] = out_lat[2];
26
    _this->p_out->data[NEW_WAYPOINT_LAT2] = out_lat[1];
27
    _this->p_out->data[NEW_WAYPOINT_LAT1] = out_lat[0];  
28
  
29
  _this->p_out->check_byte[NEW_WAYPOINT_ID] = 0x01;
30
}

Und das weiterleiten geht nicht, obwohl die Zeiger richtig gespeichert 
wurden.

kann mir jemand helfen?

MfG
Philipp

von Karl H. (kbuchegg)


Lesenswert?

Ich werde aus deiner Beschreibung nicht wirklich schlau was geht und was 
nicht geht und wie du feststellst, dass es nicht geht.

Du hast dir große Mühe gegeben, ein anständiges Design in 
objektorientierter Manier auf die Beine zu stellen. Muss man schon 
sagen.

Was du tun kannst:
Zusatzausgaben ins Programm rein!
Lass dir Pointerwerte ausgeben und kontrolliere ob in den einzelnen 
Strukturen während die Funktionen laufen auch tatsächlich die Pointer 
dorthin zeigen, wohin sie zeigen sollen. Dazu lässt du dir am Anfang die 
Adressen deiner 3 Instanzen ausgeben und vergleichst dann die Werte.
Einen Pointer kannst du dir so ausgeben lassen
1
void uart_putp( void * ptr )
2
{
3
  char buffer[10];
4
  sprintf( buffer, "%p", ptr );
5
  uart_puts( buffer );
6
}



Hier hast du dich verfranst
1
void autopilot_init(autopilot * const _this)
2
{
3
    for(unsigned char i=0;i<256;i++)
4
    {
5
        _this->wp[i].lon = 0;
6
        _this->wp[i].lat = 0;
7
        _this->wp[i].course = 0;
8
        _this->wp[i].distance = 0;
9
    }
10
    _this->wp_id = 0;
11
}
ein autopilot umfasst nur 255 waypoints.
gewöhn dir bei solchen Sachen an, die Dinge so zu formulieren, dass sich 
der Compiler um die konkreten Zahlen kümmert
1
void autopilot_init(autopilot * const _this)
2
{
3
    for(unsigned char i=0; i<sizeof(_this->wp)/sizeof(*_this->wp); i++)
4
    {
5
        _this->wp[i].lon = 0;
6
        _this->wp[i].lat = 0;
7
        _this->wp[i].course = 0;
8
        _this->wp[i].distance = 0;
9
    }
10
    _this->wp_id = 0;
11
}
dann passiert dir sowas nicht.
Ein Makro
1
#define ARRAY_SIZE(x)  (sizeof(x)/sizeof(*x))
macht die Sache dann noch besser lesbar
1
void autopilot_init(autopilot * const _this)
2
{
3
    for(unsigned char i=0; i<ARRAY_SIZE(_this->wp); i++)
4
    {
5
        _this->wp[i].lon = 0;
6
        _this->wp[i].lat = 0;
7
        _this->wp[i].course = 0;
8
        _this->wp[i].distance = 0;
9
    }
10
    _this->wp_id = 0;
11
}

von Philipp M. (lord-maricek)


Lesenswert?

Ok, danke, habe mir die Pointer mal ausgegeben, und habe dabei das 
Problem gefunden.

Ich rufe die Funktion
1
void set_gps_positon(gps * const _this,double lon,double lat)
 innerhalb einer anderen Funktion auf, an die ich schon den Zeiger auf 
gps übergeben habe.
Jetzt habe ich den Zeiger falsch übergeben.

Ich habe ihn so übergeben
1
set_gps_position(&_this,...);
Aber so gehts jetzt:
1
set_gps_position(_this,...);

MfG
Philipp

von Klaus W. (mfgkw)


Lesenswert?

Dann hättest du aber im bisherigen Programm eine Warnung sehen müssen...

von Karl H. (kbuchegg)


Lesenswert?

Das hätte sogar ein Fehler sein müssen.

 &this  hat Datentyp  gps*const*,   das const mal aussen vorgelassen
        also ein gps **

Die Funktion will aber einen gps * const, also nur einen *

von Philipp M. (lord-maricek)


Lesenswert?

Moin,

ich benutzte Avr Studio 5, und das spackt bei mir manchmal rum. Es kam 
nur heute plötzlich ne Warnung, aber es konnte Fehlerfrei kompiliert 
werden. Jetzt funtzt es jedenfalls.

MfG
Philipp

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.