Hallo zusammen,
der folgende Codeschnipsel stammt aus der Frequenzaufbereitung eines
Amateurfunkgerätes, das ich gerade baue. Verwaltet werden damit einzelne
virtuelle Oszillatoren, deren Frequenz dann jeweils in ein DDS
eingelesen wird.
Angezeigt werden soll ein String "VFO X", wobei der Buchstabe X durch
einen beliebigen Buchstaben ersetzt werden soll. Also "VFO A", "VFO B"
etc. etc. Die übergebenen Zahlenwerte in vfo_num reichen von 0 bis 12.
Analog dazu soll der Kennbuchstabe des Frequenzspeichers auf der 5.
Stelle des String landen.
Wenn ich den Code in meinem alten "Turbo C"-Compiler teste, funktioniert
es. Beim GCC für AVR (WINAVR 20100110) aber nicht. Das Ganze als Array
ginge zwar auch, will ich aber nicht. Den Buchstaben separat hinter
"VFO" schreiben wäre auch eine Alternative, aber ich will wissen, warum
das hier nicht tut.
Ich stehe gerade mal heftig auf dem Schlauch. Hilft mir jemand runter?
;-)
Viele Grüße
Peter
(DK7IH)
Peter Rachow schrieb:> Ich stehe gerade mal heftig auf dem Schlauch. Hilft mir jemand runter?> ;-)
sollte gehen, sicher das der Fehler nicht woanders ist?
Man kann es auch lesbar schreiben
reservierst Du auf dem Stack nur 5 Zeichen (einschl. dem
Nullterminator).
Garantiert ist jedenfalls nur diese Länge - mehr ist ja eigentlich auch
nicht nötig. Das Du da noch Zeichen anfügen willst, weiß der Compiler
nicht.
Ooops. Sorry.
Du reservierst nur einen Zeiger auf dem Stack der auf einen Bereich, der
jedoch nur für 5 Zeichen ausgelegt sein muss, zeigt. Wenn Du da was
anhängst, kann das schiefgehen. Geht es hier wohl auch.
Klaus schrieb:> Mit der Definition und Initialisierung> char *vfo_str = "VFO ";>> reservierst Du auf dem Stack nur 5 Zeichen (einschl. dem> Nullterminator).
ich zähle 6 Zeichen (das sind 2 Leerzeichen!)
Mac hat des Pudels Kern abgeschossen. Der Punkt ist, dass der Zeiger per
Definition nicht zwingend auf einen beschreibbaren Bereich zeigt.
Nochmal Sorry. Ich war wohl unaufmerksam.
@ Peter Rachow (Gast)
>Hi zusammen, danke für Eure zahlreichen Rückmeldungen und die>Erklärungen. Dann mache ich das mit dem Array.
Was spricht dagegen? Weil 6 Bytes auf dem Stack angelegt werden?
Was geht denn auf dem AVR gcc nicht? Kommen kryptische Zeichen raus?
Denn so oder so muss der avr gcc den String im RAM anlegen, im Flash
geht ja nicht. Also muss auch eine Manipulation des Strings möglich
sein.
*(vfo_str + 4) = vfo_num + 65;
Fehlt da nicht ein cast auf char?
Also:
(char *)(vfo_str + 4) = (char)vfo_num + 65;
Ohne handelt der Compiler das als int und schreibt das upper null byte
des Int an Stelle wo das Char hin soll.
Meinung?
Peter Rachow schrieb:> aber ich will wissen, warum> das hier nicht tut.
Weil dein Pointer auf ein String-Literal zeigt und das per Definition
für dich unberührbar ist.
Korrekt würdest du übrigens schreiben
1
constchar*vfo_str="VFO ";
womit sich dann auch der Rest erübrigt, denn dann würde dir der Compiler
auf die Finger klopfen, wenn du versuchst einen char davon zu verändern.
Gewöhn dir an const korrekt zu arbeiten.
Ja ja, schon gut.
Trotzdem, ist das nicht Performence hemmend weil vfo_str[] bei jedem
Aufruf von show_vfo() auf dem Stack erzeugt (kopiert) werden muss? So
kenne ich es aus der x86-Welt.
Wäre ein static vfo_str[] hier nicht besser? Er ändert ja sowieso immer
nur ein Byte.
Tcf K. schrieb:> Wäre ein static vfo_str[] hier nicht besser? Er ändert ja sowieso immer> nur ein Byte.
Kann man machen.
Auch wenn du den Unterschied nicht bemerken wirst. Das Ausgeben auf dem
LCD wird ein Vielfaches der Zeit der Kopieraktion benötigen.
-> Wenn du optimierst, dann optimier dort wo es Sinn macht.
Es geht um das Prinzip... ein dilettantischer Kollege hat mal eine
CRC-Routine copy&pasted, bei der er stolz die CRC-Tabelle in den
Funktionsrumpf kopiert hatte... ohne static davor! ;)
Ein anderer (eigentlicher Programmierer) hatte bei einer Funktion einen
Pointer auf eine lokale Variable der Funktion retourniert...
Das da mit einem 'alten "Turbo C"-Compiler' funktioniert, wundert mich
nicht. Mit dem Compiler aus MS VS6 gehts auch noch, mit dem aus VS2005
(oder wars doch erst VS2008?) geht es nicht mehr, da gibt es dann eine
'access violation' zur Laufzeit.