Guten Tag, Wenn ich hier völlig falsch ist, dann entschuldige ich mich.
Ich programmiere mit uVision von KEIL auf einem LPC2134 von NXP.
Ich habe folgendes vor:
Ein große Struktur die viele Variablen speichert wird deklariert.
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 deklariert.
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 initialiseirt
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 struct reserviert und der Speicher ist ja kanpp?
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?
VIELEN DANK IM VORAUS.
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)
mstp_port brauchst du eigentlich gar nicht, du kannst stattdessen
auch durchweg "&test" schreiben.
Außerdem ist es verwirrend, einen Funktionsparameter genauso zu
benennen wie eine globale Variable (auch wenn sie hier letztlich
das gleiche bezeichnen). Das erledigt sich aber von selbst, wenn
du das globale mstp_port wegwirfst.
Hilfe!
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 sturct variablen noch initialisiert werden oder
wird es mit malloc erledigt?
Nun wird die Adresse des zeigers an andere Funktion übergeben.
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?
Ich will die Adresse des Pointers an diverse Funktionen übergeben, wo
dann die Struktur manipuliert wird.
ARM schrieb:
> Hilfe!> Die Funktion MSTP_Interface_Init(); wird aufgerufen und dort wird ein> Zeiger auf die Struktur deklariert und mit malloc wird diesem Zeiger> Speicherplatz reserviert.
Nitpicking: Ausdrucksweise!
Es wird im Speicher Platz für ein Struktur-Objekt reserviert und die
Adresse dieses Speicherbereichs der Pointer Variablen zugewiesen.
> Muss hier noch mit einer sturct variablen noch initialisiert werden oder> wird es mit malloc erledigt?
malloc reserviert nur Speicher.
Sonst nichts.
>> Das Programm lässt sich kompelieren und wenn ich in debug modus gehe,> dann kann ich nicht durchsteppen.
Ungewöhnlich.
Im C Code gibt es dahingehend kein Problem.
Wie muss man sich das vorstellen, 'kann nicht durchsteppen'?
> Ich will die Adresse des Pointers an diverse Funktionen übergeben, wo> dann die Struktur manipuliert wird.
Aber du willst doch sicherlich nicht alles innerhalb einer Funktion
abhandlen, die MSTP_Interface_Init() heißt. Irgendwann wirst du doch
auch dieses Interface ausserhalb dieser Funktion benötigen, oder nicht?
Dieses Objekt zur Laufzeit mittels malloc anzulegen, ist keine so
wahnsinnig gute Idee (ausser du weißt jetzt noch nicht, ob du da 5 oder
10 oder 20 oder 100 derartige Interface Objekte benötigst). Lass das
Interface Objekt immer vorhanden sein, so gross ist das nicht. Der
Overhead und Speicherverschnitt, den du mit dem malloc erzeugst, dürfte
größer sein, als wenn du einfach immer ein Interface Objekt rumliegen
hast, es aber nicht benutzt.
Also wenn ich in Debug Modus gehedann ist einfach die Buttens Run, Step
usw. ausgegraut. Es sich so aus, als auf RUN gedruckt wurde und das
Programm häng sich auf. Ich kann aber auf Stop gehen. Einen Breakpoint
auf int main (void) setzen und wenn ich das Pogramm ausführe, dann wird
nicht zu diesem Breakpoint gesprungen.
Ich benötige nur einen solchen Object!
Dieser wird in MSTP_Interface_Init() initialisiert und in andren
Funktionen werden die Variablen innerhalb des Struktur-Objektes
manipuliert.
Ich habe das auf folgende Weise gelöst;
Zwei globale Variablen deklariert:
struct mstp_iface_struct *mstp_struct_ptr;
struct mstp_iface_struct struct_ptr;
und in der Funktion MSTP_Interface_Init() habe ich durch:
mstp_struct_ptr =&struct_ptr den Pointer initialisiert.
Soll ich besser &struct_ptr oder mstp_struct_ptr an andere Funktionen
übergeben?
Mit &struct_ptr wird doch die komplette Struktur übergegeben
und mit mstp_struct_ptr nur die Adresse von der Struktur.
Jetzt kann ich auf den mstp_struct_ptr schreiben und in anderen
Funktionen stehen die geänderte Werte zu Verfügung.
Zum Verständnis:
struct mstp_iface_struct *mstp_struct_ptr;
mstp_struct_ptr = ( struct mstp_iface_struct *)malloc (sizeof(
struct mstp_iface_struct) );
dann kann ich doch auch auf mstp_struct_ptr schreiben
mstp_struct_ptr->irgendwas = 200;
und anderen funktionen übergeben func ( mstp_struct_ptr )
ARM schrieb:
> Also wenn ich in Debug Modus gehedann ist einfach die Buttens Run, Step> usw. ausgegraut.
Interessant.
Da scheint im Debugger was nicht zu funktionieren, sobald in der
Runtime-Lib die dynamische Speicherverwaltung dazugelinkt wird.
> Ich benötige nur einen solchen Object!
Dann leg dieses eine auch statisch an.
> Dieser wird in MSTP_Interface_Init() initialisiert und in andren> Funktionen werden die Variablen innerhalb des Struktur-Objektes> manipuliert.>> Ich habe das auf folgende Weise gelöst;> Zwei globale Variablen deklariert:> struct mstp_iface_struct *mstp_struct_ptr;> struct mstp_iface_struct struct_ptr;
Die Pointer Variable brauchst du nicht.
Trägt nur zur Verwirrung bei und verbraucht zusätzlichen Speicher
> Soll ich besser &struct_ptr oder mstp_struct_ptr an andere Funktionen> übergeben?
ja.
> Mit &struct_ptr wird doch die komplette Struktur übergegeben
Nein.
& ist der Adressof-Operator.
Er liefert die Speicheradresse des Objektes auf den er angewendet wird.
Was anderes hast du hier
mstp_struct_ptr = &struct_ptr;
ja auch nicht gemacht: Die Speicheradresse von struct_ptr in
mstp_struct_ptr abzulegen.
> Zum Verständnis:> struct mstp_iface_struct *mstp_struct_ptr;> mstp_struct_ptr = ( struct mstp_iface_struct *)malloc (sizeof(> struct mstp_iface_struct) );> dann kann ich doch auch auf mstp_struct_ptr schreiben> mstp_struct_ptr->irgendwas = 200;> und anderen funktionen übergeben func ( mstp_struct_ptr )
Machs dir doch nicht so schwer.
Leg ein statisches MSTP Objekt an und gut ists. In Funktionen übergibst
du die Adresse dieses Objekts, sodass die Funktionen über diese Adresse
auf das Objekt zugreifen können. Allerdings erhebt sich die Frage: Wenn
es sowieso immer nur 1 derartiges Objekt gibt, und alle Funktionen
sowieso immer nur auf dieses 1 Objekt zugreifen, wozu sollen sie dann
die Adresse davon bekommen. Sie wissen doch ohnehin in welchem MSTP
Objekt gearbeitet werden muss.
Aber was solls
Karl heinz Buchegger schrieb:
> Die Pointer Variable brauchst du nicht.
Das schrob ich bereits im ersten Followup ganz oben. Mir scheint's
aber, dass unser OP keinerlei Plan davon hat, was er eigentlich macht
und nun versucht, das alles per trial & error zu erledigen. Das wird
nicht gut gehen.
Ohne wenigstens die Grundlagen verstanden zu haben, wie C mit Zeigern
umgeht und welche Rolle dabei der Adressoperator sowie die Dereferen-
zierung spielen, wirst du wohl auf keinen grünen Zweig kommen.
Jörg Wunsch schrieb:
> Karl heinz Buchegger schrieb:>>> Die Pointer Variable brauchst du nicht.>> Das schrob ich bereits im ersten Followup ganz oben.
Habs gesehen. Aber anscheinend glaubt er das nicht.
> Ohne wenigstens die Grundlagen verstanden zu haben, wie C mit Zeigern> umgeht und welche Rolle dabei der Adressoperator sowie die Dereferen-> zierung spielen, wirst du wohl auf keinen grünen Zweig kommen.
Yep.
Ich hab auch schon oft bemerkt, dass die Leute nach dem Muster vorgehen:
Die Funktion will einen Pointer haben, also brauch ich erst mal eine
Pointervariable.
Drum bin ich meistens so erpicht darauf, streng zwischen den Begriffen
Adresse und Pointer zu unterscheiden. Eine Adresse ist ein Wert, der in
einem Pointer gespeichert wird. Die Funktion will dann gar keinen
Pointer haben, sondern eine Adresse. Und plötzlich löst sich dann der
ganze gordische Knoten ganz von alleine auf. Ich hab eine Adresse, die
krieg ich mit & und die Funktion will eine Adresse (welche dann während
der Funktionsausführung in einem Pointer gespeichert wird), passt also
perfekt.
Vielen Dank für eure Beiträge.
Ich habs mit der Adressübergabe realisiert, ist wirklich viel einfacher.
Vielen Dank.
Ich will was ähnliches realisieren siehe Anhang.
Und dort wird ein Adresse der Stuctur der Pointervariablen übergeben.
(siehe mstp.h ganz unter).
Übrigens
das Problem mit malloc() 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.
ARM schrieb:
> Übrigens>> das Problem mit malloc() 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.
Malloc braucht immer Heap. Wenn µVision, dann bitte im Startup-File (ev.
zum Config-Wizard umschalten) die entsprechende Menge Heap reservieren.
Sonst kann der Schuss nach hinten losgehen.
Es gibt auch Funktionen (z.B. fprintf) die ohne heap nicht immer
auskommen, da kann man auch in ne böse Falle treten.
VG,
/th.