Forum: PC-Programmierung Adresse vom Struct global speichern um später drauf zu schreiben


von Jan (Gast)


Lesenswert?

Hallo,
ich habe eine Funktion der ein Struct als Pointer übergeben wird
1
void start (Message * const TxMessage)
und eine Funktion die jede 10 ms (aus einer anderen Funktion) aufgerufen 
wird
1
void writeInterface(void)
(Das aber nur, wenn start vorher aufgerufen wurde).
Jetzt möchte ich in der writeInterface-Funktion TxMessage beschreiben.
Dazu würde ich die Adresse vom Pointer in der Funktion start auf eine 
Globale variable speichern.

Hieran scheitere ich allerdings gerade. Ist meine Idee so überhaupt 
möglich?

Hat jemand einen Tip, was/wie ich es genau machen muss?

von Jan (Gast)


Lesenswert?

Ahso, was ich bisher versucht habe ist eine globale variable zu 
erstellen
static Message TxMessageGlobal

und in der Funktion Start+
1
 TxMessage = &TxMessageGlobal;
TxMessageGlobal würde ich dann in der Funktion writeInterface benutzen.
1
 TxMessageGlobal.size = 0x01;
2
 TxMessageGlobal.value[0]= 0x7F;
 Allerdings stürtzt das Programm immer beim beschreiben immer ab

von foobar (Gast)


Lesenswert?

>  TxMessageGlobal.size = 0x01;
>  TxMessageGlobal.value[0]= 0x7F;
>
> Allerdings stürtzt das Programm immer beim beschreiben immer ab

Ist .value evtl ein (nicht initialisierter) Pointer?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Jan schrieb:
> Dazu würde ich die Adresse vom Pointer in der Funktion start auf eine
> Globale variable speichern.

Kann man so machen. Aber das machst Du nicht :

> static Message TxMessageGlobal

Das ist kein Pointer, und das ist keine globale Variable, sondern nur 
eine innerhalb des Moduls/der "translation unit" sichtbare Variable.

> TxMessage = &TxMessageGlobal;

Das setzt den der Funktion übergebenen Wert auf die Adresse der globalen 
Variablen.

Du willst zwei andere Dinge erreichen:

a) Deine "globale" Variable soll ein Pointer werden

b) Du willst in start diesem Pointer den der Funktion übergebenen 
Pointer zuweisen.
1
Message *TxMessageGlobal;
2
3
void start (Message * const TxMessage)
4
{
5
  TxMessageGlobal = TxMessage;
6
7
  // ... 
8
}
9
10
void writeInterface(void)
11
{
12
  if (TxMessageGlobal)
13
  {
14
    TxMessageGlobal->size = 0x01;
15
    TxMessageGlobal->value[0]= 0x7F;
16
  }
17
}

Das "if (TxMessageGlobal)" prüft, ob dem Pointer bereits ein Wert 
zugewiesen wurde.

Dieser Pointer ist ohne den Aufruf von "start" per Default mit NULL 
initialisiert, und das kann auf diese Art und Weise erkannt werden.



Voraussetzung dafür, daß das ganze was sinnvolles macht, ist, daß der 
der Funktion start übergebene Pointer auf einen dauerhaft mit Inhalt 
versehenen Speicherbereich zeigt (und nicht nur auf eine in der 
Aufruferfunktion lokale Variable).

: Bearbeitet durch User
von Jan (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Kann man so machen. Aber das machst Du nicht :

Ja, das ganze mit den Pointern tu ich mich noch ein bisschen schwer mit.

Aber so wie du es vorgemacht hast, funktioniert es. Meine Idee an sich 
hat also funktioniert, nur bei der Umsetzung bin ich gescheitert.

Du hast geschrieben "Kann man so machen.". Was gäbe es denn anderes als 
Alternative?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Jan schrieb:
> Was gäbe es denn anderes als Alternative?

Kann man, ohne den Kontext zu kennen, schwer beantworten.

Woher kommt der der Funktion start übergebene Pointer?

von foobar (Gast)


Lesenswert?

Ich schrieb:
> Ist .value evtl ein (nicht initialisierter) Pointer?

Man sollte nicht vorm ersten Kaffee antworten, die Antwort gehört wohl 
zur "Not even wrong" Klasse - nicht falsch, aber irrelevant.

Zum Ausgleich etwas, warum dein Ansatz verkehrt sein dürfte/könnte:

Man muß bei solchen Sachen im Auge haben, wem das Objekt gehört und 
entsprechend, wer damit hantieren darf.

Üblich bei solchen Funktionen wie deinem "start" ist, dass das Objekt 
(die TxMessage) dem Aufrufer gehört und er es dieser Funktion für eine 
Weile überlässt.  Was die Funktion währenddessen damit machen darf, 
steht irgendwo in der Systembeschreibung (z.B. lesen ok, ändern 
verboten).  Sobald die Funktion zurückkehrt, ist wieder der Aufrufer der 
Verantwortliche - er kann das Objekt jetzt für andere Aktionen 
verwenden, es wieder freigeben oder sonstwas mit machen.

In einigen Fällen wird das Objekt der Funktion auf Dauer übergeben 
(Besitzerwechsel).  Der Aufrufer wird es nicht mehr anfassen, auch wenn 
die Funktion zurückgekehrt ist.  Sie hat sich jetzt darum zu kümmern, 
dass das Objekt irgendwann wieder freigegeben wird, etc - sie bestimmt 
die Lebensdauer.

Welcher Fall vorliegt, kann man so nicht sagen, das hängt von deinem 
konkreten Programm/System ab - das meinte Rufus mit "ohne Kontext schwer 
zu sagen".

Im ersten Fall wäre deine Methode verkehrt: sie würde das Objekt ändern, 
das ihr gar nicht mehr gehört - evtl nicht mal mehr existiert (sprich, 
du schreibst wild im Speicher herum).

Im zweiten Fall müßtest du dich darum kümmern, dass das Objekt auch 
irgendwann wieder freigegeben wird, sonst läuft irgendwann dein Speicher 
über.

Wenn man in einer solchen Bredouille steckt, ist das oft ein Zeichen, 
dass man die API falsch benutzt.

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.