Forum: Compiler & IDEs Bestimmter Speicheradresse einen Wert zuweisen


von Alex (Gast)


Lesenswert?

Hallo zusammen,

ich sitze gerade an einem Projekt für den ATmega644 und möchte wie 
erwähnt an eine Speicheradresse einen Wert schreiben. Dabei ist die 
Speicheradresse als int gegeben. fptr ist ein vorher definierter 
Funktionspointer-Typ.

1
fptr tmp;
2
tmp=(fptr)Speicherdresse;
3
*tmp=Wert;

Dabei erhalte ich folgende Fehlermeldung für die 3. Zeile:
error: lvalue required as left operand of assignment

Könnt ihr mir sagen wo da mein Fehler liegt? Lässt sich das gar nicht so 
einfach realisieren?

Gruß
Alex

von Werner B. (werner-b)


Lesenswert?

MoingMoing!

Es stellt sich die Frage
 Was ist "fptr"?

Jedenfalls kein vordefinierter "C" Datentyp.
Ohne diese Information kann dir niemand helfen.

von der mechatroniker (Gast)


Lesenswert?

Wenn fptr tatsächlich ein Funktionspointer ist, also z.B.
1
typedef void fptr(int);
dann ist klar, dass das nicht geht, wie willst du an eine Funktion einen 
Wert zuweisen?

Wenn du die Funktion mit dem Wert als Übergabeparameter aufrufen willst, 
geht das mit
1
fptr(Wert);

Also: was hast du vor?

von Imon (Gast)


Lesenswert?

Ich bin mir nicht sicher was du vor hast aber eine bestimmten Speicher 
Adresse  einen wert zu weisen, macht man so
1
 
2
 char *ptr;
3
4
 ptr = ( char *) 0xDEADBEEF; // Setze Address auf 0xDEADBEEF;
5
 *ptr = WERT;  // schreibe WERT nach 0xDEADBEF;

von Klaus W. (mfgkw)


Lesenswert?

Das würde ein Byte zuweisen.

Er redet aber davon, eine int übertragen zu wollen.
Das ginge analog mit:
1
  int wert = ...; // was auch immer
2
  / an die Adresse 0xDEADBEEF die int WERT schreiben:
3
  *(int*)0xDEADBEEF = wert;

Aber was er wirklich will, ist mir auch nicht so recht klar.
DSas obige setzt ja eine Speichrstelle im RAM.
Ein Funktionszeiger würde aber gar nicht eine RAM-Adresse
beinhalten beim AVR.

von Oliver (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> DSas obige setzt ja eine Speichrstelle im RAM.

Nö. Das weisst lediglich dem Pointer einen Wert zu. Der würde bei Aufruf 
der Funktion über den Pointer als Adresse im Flash interpretiert.

Alex schrieb:
> *tmp=Wert;
>
> Dabei erhalte ich folgende Fehlermeldung für die 3. Zeile:
> error: lvalue required as left operand of assignment

Nun ja, ein Funktionspointer ist ein Funktionspointer ist ein 
Funktionspointer. Das, worauf der zeigt (*tmp), ist eine Funktion, die 
kann man nur aufrufen, aber der kann man keinen Wert zuweisen.

Daher solltest du erst einmal beschreiben, was du eigentlich erreichen 
willst.

Oliver

von Alex (Gast)


Lesenswert?

Vielen Dank für die vielen Antworten!

Ich war gestern Nacht wohl schon übermüdet und es hat am elementaren 
Verständnis für Pointer gefehlt.

Mithilfe von Imons Beitrag konnte ich mein Problem schon lösen.
Mein Problem dabei war das mein WERT die Adresse einer Funktion ist. 
(WERT ist also ebenfalls vom Typ fptr)
Ich wollte aber keine Funktion speichern sondern eben nur einen int-Wert 
der die Adresse einer Funktion beschreibt.

Der von mir gesuchte Code sieht also so aus:
1
unsigned int* tmp;
2
tmp=(unsigned int*)Speicherdresse;
3
*tmp=(unsigned int)WERT;

Das müsste eigentlich das tun was ich wollte.

Gruß
Alex

von Klaus W. (mfgkw)


Lesenswert?

Und wozu dann tmp?
*(unsigned int*)Speicherdresse=(unsigned int)WERT;

von Alex (Gast)


Lesenswert?

Edit:

Wahrscheinlich wäre unsigned char, sinniger als unsigned int wenn ich 
die Adresse einer Funktion speichern möchte, oder?

von Klaus W. (mfgkw)


Lesenswert?

In ein char passt nur ein Byte.
Es gibt nicht viele Systeme, bei denen die Adresse einer
Funktion mit einem Byte auskommt.

int bzw. uint muß auch nicht passen, geht aber oft (zufällig).

Ich weiß immer noch nicht, was du wirklich willst.
Aber es kommt mir falsch vor.

von Klaus W. (mfgkw)


Lesenswert?

PS:
Daß in C Adressen auch nur Zahlenwerte sind, heisst nicht, daß
es auch nur im Mindesten sinnvoll wäre Adressen und andere
Zahlen wild zu pürieren.
Das ist in 99% der Fälle böses Gemurkse und führt zu nichts,
zumindest wenn man nicht weiß was man tut.

von Alex (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Und wozu dann tmp?
> *(unsigned int*)Speicherdresse=(unsigned int)WERT;

Das ist natürlich noch einfacher.

Habs mal getestet und char ist wirklich zu klein für meine Zwecke.
Meine Fragen sind glaube ich alle geklärt. Danke :)

Gruß
Alex

von Karl H. (kbuchegg)


Lesenswert?

Alex schrieb:
> Edit:
>
> Wahrscheinlich wäre unsigned char, sinniger als unsigned int wenn ich
> die Adresse einer Funktion speichern möchte, oder?


Am sinnigsten wäre es, ganz einfach den dafür vorgesehenen Datentyp, 
nämlich einen Funktionspointer, zu benutzen.

Speziell bei Pointer gilt nämlich oft die Daumenregel: Wenn man da wie 
wild rumcasten muss, dann stimmt etwas nicht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karl heinz Buchegger schrieb:
> Speziell bei Pointer gilt nämlich oft die Daumenregel: Wenn man da wie
> wild rumcasten muss, dann stimmt etwas nicht.

Außerdem dürfen Funktionszeiger ohnehin nur in (bzw. von) anderen
Funktionszeigern gecastet werden, eine Vermischung mit Objektzeigern
ist unzulässig und führt zu undefiniertem (meiner Erinnerung nach)
Verhalten.  Auch ein Cast von/nach "void *" ist damit unzulässig.
Wenn man einen "generischen" Funktionszeiger braucht (um einen Zeiger
auf eine Funktion beliebigen Typs speichern zu können, bei dem Typ
und Anzahl der Argumente erst zur Laufzeit feststehen), kann man
sich mit sowas helfen:
1
typedef void (*generic_func_ptr)(void);

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.