func (werte->struct) func(werte lesen geht nicht)

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
SeriK00
Beiträge: 34
Registriert: Fr Mai 15, 2009 12:15 pm

func (werte->struct) func(werte lesen geht nicht)

Beitrag von SeriK00 » Di Jun 16, 2009 12:39 am

Guten Abend,
ich brauch mal eure Hilfe.
Ich habe ein Struktur definiert, die enums und Variablen enthält.
Der Funktion mstp_create_frame ( mstp_port ) wird ein Pointer auf die Struktur übergegeben.
Mit Hilfe des Pointers *mstp_port werden die Werte in der Struktur deklariert.

void MSTP_Receive_Frame_State_Machhine( struct mstp_port_struct *mstp_port )
Mit Hilfe von dieser Funktion wollte ich auf die Werte in struct zugriefen, doch da stehen nicht die von mir zugewisenen Werte.

Woran kann das liegen???
Vielen Dank im Voraus.

Code: Alles auswählen


typedef enum
{
 	MSTP_RECEIVE_FRAME_STATE_IDLE =					0,
	MSTP_RECEIVE_STATE_FRAME_PREAMBLE =			1,
	MSTP_RECEIVE_STATE_FRAME_HEADER =				2,
	MSTP_RECEIVE_STATE_FRAME_HEADER_CRC =			3,
	MSTP_RECEIVE_STATE_FRAME_DATA =				4,
	MSTP_RECEIVE_STATE_FRAME_DATA_CRC =			5
} MSTP_RECEIVE_FRAME_STATE;


struct mstp_port_struct  
{
	MSTP_RECEIVE_FRAME_STATE receive_frame_state;
	unsigned char preamble1;
	unsigned char preamble2;
	unsigned char frame_type1;
	unsigned char destination;
	unsigned char source;
};
struct mstp_port_struct *mstp_port;



int main (void)
{
       mstp_create_frame ( mstp_port );	
       MSTP_Receive_Frame_State_Machhine( mstp_port ); 	
}



void mstp_create_frame ( struct mstp_port_struct *mstp_port )			
{
	int i;
	struct mstp_port_struct test;
	mstp_port = &test;
	memset(mstp_port, 0, sizeof(struct mstp_port_struct));
	mstp_port->receive_frame_state = MSTP_RECEIVE_STATE_FRAME_HEADER;	
	mstp_port->preamble1 = 		55;
	mstp_port->preamble2 = 		255;
	mstp_port->frame_type1 =    	0;
	mstp_port->destination = 		80;
	mstp_port->source = 			81;
}



void MSTP_Receive_Frame_State_Machhine( struct mstp_port_struct *mstp_port )
{
    if (mstp_port->receive_frame_state == MSTP_RECEIVE_STATE_FRAME_HEADER ) //mstp->receive_frame_state steht was falsches. Da sollte eigentlich 2 stehen (MSTP_RECEIVE_STATE_FRAME_HEADER =				2)
   {
  	int i;
	i=5;
   }
}
Windows XP Prof
Visual Studion 2005
Keil µVision 3

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: func (werte->struct) func(werte lesen geht nicht)

Beitrag von Xin » Di Jun 16, 2009 5:01 am

SeriK00 hat geschrieben:Mit Hilfe von dieser Funktion wollte ich auf die Werte in struct zugriefen, doch da stehen nicht die von mir zugewisenen Werte.

Woran kann das liegen???
Vielen Dank im Voraus.

Code: Alles auswählen

struct mstp_port_struct *mstp_port;

int main (void)
{
       mstp_create_frame ( mstp_port );	
       MSTP_Receive_Frame_State_Machhine( mstp_port ); 	
}

void mstp_create_frame ( struct mstp_port_struct *mstp_port )			
{
	int i;
	struct mstp_port_struct test;
	mstp_port = &test;
}
Typischer Anfängerfehler.
Die lokalen Variablen werden auf einem Stack aufgebaut. Ruft man die Funktion mstp_create_frame, so wird die Struktur test auf dem Stack angelegt. Anschließend weißt Du die Adresse der Struktur des Stacks auf mstp_port zu. Nun verlässt Du die Funktion, die Struktur test wird zerstört (also zeigt mstp_port) auf den Speicher, wo früher mal test stand. Beim nächsten Funktionsaufruf werden genau(!) an der Stelle neue Daten abgelegt und überschreiben damit die Werte, auf die mstp_port weiterhin zeigt....

Du musst mit new oder malloc eienen Speicher anfordern und ihn anschließend mit delete bzw. free() wieder freigeben.
Ich empfehle void mstp_create_frame( struct mstp_port_struct * mstp_port ) in struct mstp_port_struct * mstp_port mstp_create_frame( void ) umzubauen und allgemein kürzere Bezeichnungen einzufügen. In struct mstp_port_struct wiederholt sich z.B. das struct.


Hierfür bräuchten wir einen FAQ-Eintrag...
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

SeriK00
Beiträge: 34
Registriert: Fr Mai 15, 2009 12:15 pm

Re: func (werte->struct) func(werte lesen geht nicht)

Beitrag von SeriK00 » Di Jun 16, 2009 10:20 pm

Hallo Xin.
Vielen dank für deine Anwort.
Ich bin ein Anfänger deswegen hacke ich nach (ich programmiere übrigens auf dem uController)

Ich habe folgedes for:

Ein große Struktur die viele Variablen speicher wird definiert
Mit Hilfe von diversen Funktionen wird die Struktur manipuliert.
Eine Funktion speicher einen Wert in der Struktur, die andere liest diesen Wert aus und eine anderer Funktion speichert einen neuen Wert usw.

Ist meine Lösung ok?
Wie mache ich das am besten?

Hier habe ich noch einige Fragen zum Verständnis:

1. Es wird ein Pointer auf die Struktur definiert.
struct mstp_port_struct *mstp_port;
Das heißt doch es gibt einen Zeiger von Typ (Datentyp) der Struktur, aber dieser weiß nicht wohin er zeigen soll, weil er nicht deklariert wurde?

2. Es wird eine Variablen definiert:
struct mstp_port_struct test;
Die Variable test ist von dem Typ der Struktur und enthält alle Variablen die in der Struktur stehen.
Ich könnte auch diese Variable an die Funktion übergeben, weil aber die Funktion groß ist, wird ein Zeiger übergeben, welche die Adresse von Strukturvariablen hat


3.Die beiden Variablen:
struct mstp_port_struct *mstp_port;
struct mstp_port_struct test;

wurden vor main definiert und sind damit global in main reserviere ich Speicher und
weiße die Adresse von Test dem Pointer zu.
Ist es ok wenn ich die Variablen global definiere?
Denn durch diese Zuweisung: mstp_port_struct wird Speicher in der Größe von strukt reserviert und diese ist ziemlich groß?

4. in main() rufe ich Funktionen aus und übergeben mstp_port (die Adresse des Pointers)

5. Diesen Aufruf habe ich abgequckt auf einem Beispiel, welches genau meine Aufgabe realisiert:
void mstp_create_frame ( volatile struct mstp_port_struct *mstp_port )
Was hat dieser volatile für ein Zweck hier?

6. Da aber der Pointer global ist, kann ich auch die Funktionen ohne Parameter aufrufen:
mstp_create_frame ( void );
MSTP_Receive_Frame_State_Machhine( void
und die Stuktur auf folgende weise manipulieren:
void MSTP_Receive_Frame_State_Machhine( void )
{
if (mstp_port->receive_frame_state == MSTP_RECEIVE_STATE_FRAME_HEADER )
{
printf("\n%d", mstp_port->destination);
printf("\n%d", mstp_port->receive_frame_state);
}
also mit Parametern und Argumenten oder mit void?

7. struct mstp_port_struct * mstp_port mstp_create_frame( void )
Das habe ich nicht ganz verstanden. Kann mir das jemand an einem einfachen Beispiel erklären?

VIELEN DANK IM VORAUS.

Code: Alles auswählen

#include "stdafx.h"
#include <stdlib.h>
#include <string.h>

typedef enum
{
   MSTP_RECEIVE_FRAME_STATE_IDLE =               0,
   MSTP_RECEIVE_STATE_FRAME_PREAMBLE =         1,
   MSTP_RECEIVE_STATE_FRAME_HEADER =            2,
   MSTP_RECEIVE_STATE_FRAME_HEADER_CRC =         3,
   MSTP_RECEIVE_STATE_FRAME_DATA =            4,
   MSTP_RECEIVE_STATE_FRAME_DATA_CRC =         5
} MSTP_RECEIVE_FRAME_STATE;


struct mstp_port_struct 
{
   MSTP_RECEIVE_FRAME_STATE receive_frame_state;
   unsigned char preamble1;
   unsigned char preamble2;
   unsigned char frame_type1;
   unsigned char destination;
   unsigned char source;
};
struct mstp_port_struct *mstp_port;
struct mstp_port_struct test;
 

void MSTP_Receive_Frame_State_Machhine( volatile struct mstp_port_struct *mstp_port );
void mstp_create_frame ( volatile struct mstp_port_struct *mstp_port );

int main (void)
{
	       memset(mstp_port, 0, sizeof(struct mstp_port_struct));
		mstp_port = &test;
		mstp_create_frame ( mstp_port );   
		MSTP_Receive_Frame_State_Machhine( mstp_port ); 
		return 0;
		free(mstp_port);
}

void mstp_create_frame ( volatile struct mstp_port_struct *mstp_port )         
{

   mstp_port->receive_frame_state = MSTP_RECEIVE_STATE_FRAME_HEADER;   
   mstp_port->preamble1 =       55;
   mstp_port->preamble2 =       255;
   mstp_port->frame_type1 =       0;
   mstp_port->destination =       80;
   mstp_port->source =          81;
   printf("\n%d", mstp_port->destination);
}



void MSTP_Receive_Frame_State_Machhine( volatile struct mstp_port_struct *mstp_port )
{
    if (mstp_port->receive_frame_state == MSTP_RECEIVE_STATE_FRAME_HEADER ) //mstp->receive_frame_state steht was falsches. Da sollte eigentlich 2 stehen (MSTP_RECEIVE_STATE_FRAME_HEADER =            2)
   {
	   printf("\n%d", mstp_port->destination);
	   printf("\n%d", mstp_port->receive_frame_state);
   }
}
Windows XP Prof
Visual Studion 2005
Keil µVision 3

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: func (werte->struct) func(werte lesen geht nicht)

Beitrag von Xin » Mi Jun 17, 2009 9:16 am

SeriK00 hat geschrieben:Ich bin ein Anfänger deswegen hacke ich nach (ich programmiere übrigens auf dem uController)
Das ist der Sinn dieses Forums ^^
Typischer Anfängerfehler sollte auch nicht böse gemeint sein - ist halt einer.
SeriK00 hat geschrieben:Eine Funktion speicher einen Wert in der Struktur, die andere liest diesen Wert aus und eine anderer Funktion speichert einen neuen Wert usw.
Ist meine Lösung ok?
Wie mache ich das am besten?
Ich halte nichts von Funktionen, die einzelne Werte auslesen. Wenn Du Werte auslesen möchtest, dann lies sie halt aus und fertig.
Verstehe Strukturen als Beschreibung eines Objektes.
Beispiel: struct Auto mit Hersteller, Farbe, Position, Kilometerleistung, Tankstand.
Wenn Du nun eine Funktion fahre(struct Auto *auto, Position * ziel) schreibst, veränderst Du den Tankstand in Abhängigkeit von der Entfernung und die Entfernung addierst Du auf Kilometerleistung drauf. Das ist eine Funktion.
Wenn Du nur die Farbe wissen willst, dann sag das auch: mein Auto->Farbe.
SeriK00 hat geschrieben:1. Es wird ein Pointer auf die Struktur definiert.
struct mstp_port_struct *mstp_port;
Das heißt doch es gibt einen Zeiger von Typ (Datentyp) der Struktur, aber dieser weiß nicht wohin er zeigen soll, weil er nicht deklariert wurde?
Deklariert hast Du ihn grade. ;-)
Auch definiert ist er nun.
Aber er ist nicht initialisiert, also zeigt er irgendwohin.
SeriK00 hat geschrieben:2. Es wird eine Variablen definiert:
struct mstp_port_struct test;
Die Variable test ist von dem Typ der Struktur und enthält alle Variablen die in der Struktur stehen.
Ich könnte auch diese Variable an die Funktion übergeben, weil aber die Funktion groß ist, wird ein Zeiger übergeben, welche die Adresse von Strukturvariablen hat.
Du gibst &test zurück. Wenn Du es weitergibst, an Funktionen, die Du aufrufst, dann hast Du es kein Problem. Aber Du gibst es zurück und verlässt die Funktion. Das gibt Ärger...
SeriK00 hat geschrieben: 3.Die beiden Variablen:
struct mstp_port_struct *mstp_port;
struct mstp_port_struct test;

wurden vor main definiert und sind damit global in main reserviere ich Speicher und
weiße die Adresse von Test dem Pointer zu.
Ist es ok wenn ich die Variablen global definiere?
Es ist nicht schön, aber auch nicht verboten.

Wenn möglich verzichte auf globale Variablen. Im Idealfall hast Du keine globalen Variablen.
SeriK00 hat geschrieben:Denn durch diese Zuweisung: mstp_port_struct wird Speicher in der Größe von strukt reserviert und diese ist ziemlich groß?
Wird sich wohl im Rahmen halten.
SeriK00 hat geschrieben:4. in main() rufe ich Funktionen aus und übergeben mstp_port (die Adresse des Pointers)

5. Diesen Aufruf habe ich abgequckt auf einem Beispiel, welches genau meine Aufgabe realisiert:
void mstp_create_frame ( volatile struct mstp_port_struct *mstp_port )
Was hat dieser volatile für ein Zweck hier?
volatile heißt, dass die CPU des Controllers den Zeiger nicht im Register behalten darf, sondern änderungen sofort zurückschrieben muss.
SeriK00 hat geschrieben:6. Da aber der Pointer global ist, kann ich auch die Funktionen ohne Parameter aufrufen:
mstp_create_frame ( void );
MSTP_Receive_Frame_State_Machhine( void
und die Stuktur auf folgende weise manipulieren:
void MSTP_Receive_Frame_State_Machhine( void )
{
if (mstp_port->receive_frame_state == MSTP_RECEIVE_STATE_FRAME_HEADER )
{
printf("\n%d", mstp_port->destination);
printf("\n%d", mstp_port->receive_frame_state);
}
also mit Parametern und Argumenten oder mit void?
Wenn Du ohne globale Variablen arbeitest, dann mit Parameter.

Controller zu programmieren ist ein wenig anders als Anwendungen. Aber ein Controller ist inzwischen auch nicht mehr ganz ohne Speicher. Ich plädiere auf Sicherheit zu programmieren => keine globalen Variablen.
SeriK00 hat geschrieben:7. struct mstp_port_struct * mstp_port mstp_create_frame( void )
Das habe ich nicht ganz verstanden. Kann mir das jemand an einem einfachen Beispiel erklären?

Code: Alles auswählen

struct mstp_port_struct * mstp_port mstp_create_frame( void ) 
{
  return (struct mstp_port_struct *) malloc( sizeof( struct mstp_port_struct ) );
}
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

SeriK00
Beiträge: 34
Registriert: Fr Mai 15, 2009 12:15 pm

Re: func (werte->struct) func(werte lesen geht nicht)

Beitrag von SeriK00 » Mi Jun 17, 2009 12:57 pm

Vielen Dank für diese ausführliche Beschreibung!

Ich arbeite dann ohne globalen Variablen.

Die Funktion MSTP_Interface_Init(); wird aufgerufen und dort wird ein Zeiger auf die Struktur deklariert und mit malloc wird diesem Zeiger Speicherplatz reserviert.
Muss hier noch mit einer struct variablen der Pointer initialiseirt werden
also noch sowas wie:
struct mstp_iface_struct var;
mstp_struct_ptr = &var;
oder wird es mit malloc erledigt?

Nun wird die Adresse des zeigers an andere Funktion übergeben.
Ich will nur den zeiger an die Funktionen übergeben, die Funktionen greifen dann in die Struktur und manipulieren Werte und Speichern veränderte Werte ab.
Die neuen Werte stehen dann in anderer Funktionen zu Verfügung.
Die Adresse der struktur variablen will ich nicht übergeben, weill in der struct stehen mehr als 50 Variablen und nicht alle diese Werte in einer Funktion geändert.


Das Programm lässt sich kompelieren und wenn ich in debug modus gehe, dann kann ich nicht durchsteppen. Klammere ich die Anweisung mit malloc aus, verschwindet das Problem.
Ich arbeite mit uVision von Keil. Hab mein code in Studio ausprobiert und es klappte.
Wo kann das Problem liegen? Habe ich irgendwo einen Fehler?

Code: Alles auswählen

struct mstp_iface_struct  
{
	unsigned char preamble1;
	unsigned char preamble2;
	unsigned char frame_type1;
	unsigned char destination;
	unsigned char source;
						
};


void MSTP_Interface_Init( void );
void MSTP_Master_Node_State_Machine ( struct mstp_iface_struct *mstp_ptr );
int main ()
{
    MSTP_Interface_Init();
}

void MSTP_Interface_Init( void )
{
	struct mstp_iface_struct *mstp_struct_ptr;
	mstp_struct_ptr = ( struct mstp_iface_struct *)malloc (sizeof(      struct  mstp_iface_struct) );


	mstp_struct_ptr->preamble1 = 5;
	MSTP_Master_Node_State_Machine ( mstp_struct_ptr );
}

void MSTP_Master_Node_State_Machine ( struct mstp_iface_struct *mstp_ptr )
{ 
  mstp_port->.....
}
Windows XP Prof
Visual Studion 2005
Keil µVision 3

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: func (werte->struct) func(werte lesen geht nicht)

Beitrag von Kerli » Do Jun 18, 2009 11:48 am

SeriK00 hat geschrieben:Muss hier noch mit einer struct variablen der Pointer initialiseirt werden
also noch sowas wie:
struct mstp_iface_struct var;
mstp_struct_ptr = &var;
oder wird es mit malloc erledigt?
Nein, das passt schon so. malloc reserviert den gewünschten Speicher und gibt die Adresse zurück an der dieser Speicher liegt.
SeriK00 hat geschrieben:Das Programm lässt sich kompelieren und wenn ich in debug modus gehe, dann kann ich nicht durchsteppen. Klammere ich die Anweisung mit malloc aus, verschwindet das Problem.
Ich arbeite mit uVision von Keil. Hab mein code in Studio ausprobiert und es klappte.
Wo kann das Problem liegen? Habe ich irgendwo einen Fehler?
Den einzigen Fehler den ich gefunden habe ist das es in der letzten Funktion wohle eher 'mstp_ptr' statt 'mstp_port' heißen sollte, aber dann dürfte er nicht einmal kompilieren. Komisch, ich kann das bei mir problemlos debuggen. Vielleicht hat dein Mikrocontroller irgendein Problem mit malloc und verwendet dafür etwas eigenes.
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

SeriK00
Beiträge: 34
Registriert: Fr Mai 15, 2009 12:15 pm

Re: func (werte->struct) func(werte lesen geht nicht)

Beitrag von SeriK00 » Do Jun 18, 2009 5:11 pm

Vielen Dank,

das Problem lag bei mir im Heap.
Der wurde mit 0 Bytes angegeben, die Struktut benötigt aber 12 Bytes.
Aber auch wenn ich nur 9 Bytes dem Heap zuweise, klappt's.
Kommisch.
Windows XP Prof
Visual Studion 2005
Keil µVision 3

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: func (werte->struct) func(werte lesen geht nicht)

Beitrag von Xin » So Jun 21, 2009 11:38 am

SeriK00 hat geschrieben:Vielen Dank,

das Problem lag bei mir im Heap.
Der wurde mit 0 Bytes angegeben, die Struktut benötigt aber 12 Bytes.
Aber auch wenn ich nur 9 Bytes dem Heap zuweise, klappt's.
Kommisch.
Ich gehe davon aus, dass die Adressen long-aligned sind, also durch vier teilbar. Wenn Du 9 Bytes anforderst bekommst du die nächst größere Menge, die durch vier teilbar ist: 12 Bytes.
Bitte experimentiere nicht mit sowas. Wenn Du 12 haben willst, fordere auch 12 an.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten