Member since Jul 2011
1 post
|
![]()
Subject: Zeiger
Kann man mit Zeigern schreibgeschützte Datenbereiche manipulieren?
Dies war eine mögliche Antwort bei den Multiple-Choice Aufgaben zu Zeigern. |
Member since May 2011
331 posts
|
![]()
Sind sie dann schreibgeschützt?
|
Member since Oct 2010
53 posts
|
![]()
Nö, es geht nicht.
Was beim Versuch eines Schreibzugriffs passiert, kommt darauf an, auf was für Hardware du läufst:
|
Member since May 2011
212 posts
|
![]()
Wenn ich eine Konstante habe und einen Zeiger so setze, dass er auf den Speicherbereich der Konstanten zeigt, kann ich die Konstante aber überschreiben oder?
|
Member since May 2011
331 posts
|
![]()
Das kommt drauf an. Beim AVR ist dies der Fall, weil dieser keinen Schreibgeschützten Datenspeicher unterstützt - bei anderen Prozessoren sieht das schon ganz anders aus. Das const Schlüsselwort sagt dem Compiler lediglich, dass sich der Wert nicht ändert und er ihn entsprechend behandeln soll (Optimierung + Fehler, wenn man darauf schreibt). Das heißt aber noch lange nicht, dass sich dieser nicht ändern kann. Es ist so mehr oder weniger das Gegenteil von Volatile - Das sagt ja auch nur, dass sich der Speicher unerwartet ändern kann, aber nicht, dass er das auch tut.
Wenn die Plattform jedoch schreibgeschützte Datenbereiche unterstützt, dann wird der Compiler und Linker _im Normallfall_ versuchen die Variable dort abzulegen - muss er aber nicht. In Wirklichkeit ist das noch einen Ticken komplizierter, aber ich hoffe, dass das jetzt etwas zum Verständnis beiträgt. |
Member since Oct 2010
53 posts
|
![]()
Grundsätzlich gilt: Wenn du böse Tricksereien wie das Wegcasten von const treibst, hast du kein nach dem C-Sprachstandard gültiges Programm mehr. Was das Programm an der betreffenden Stelle tatsächlich tut, ist undefiniert.
Wenn du Glück hast, passiert tatsächlich das, was du denkst, und das Schreiben funktioniert. Wenn du weniger Glück hast, passiert entweder gar nichts oder die Anwendung wird durch das Betriebssystem kontrolliert beendet ("stürzt ab"). Wenn du ganz ganz großes Pech hast, löscht das Programm deine Festplatte, exmatrikuliert dich von der Uni und schreibt deiner Freundin eine SMS mit dem Inhalt "Du bist mir zu fett". Undefiniertes Verhalten halt! ![]() ... Und deswegen will man sich nicht auf irgendwelche kranken Hacks verlassen, sondern immer bewusst sauber programmieren. ![]() |
Member since May 2011
109 posts
|
![]()
heißt das, man könnte doch irgendwie einen Zähler basteln, der zählt, wie oft man den µC eingeschaltet hat??
Variable=0; main(){ Variable++; //auf irgendeine kranke Art und Weise while(1){ Variable anzeigen } } |
Member since May 2011
331 posts
|
![]()
Wie kommst du zu dieser Schlussfolgerung? (Ja, kann man, aber auch das ist aufwendiger und geht über den Stoff von SPiC hinaus). |
Member since Oct 2010
53 posts
|
![]()
Einfach so vom Programm aus ins ROM schreiben funktioniert nicht.
Was morty gestern meinte, war Folgendes: Unter Umständen werden Werte, die eigentlich unveränderlich sein sollten, beim Start in den (schreibbaren) RAM geladen. Wenn man genau Bescheid weiß, kann man diese Speicherstellen vom Programm aus gezielt überschreiben. Sobald man den Stecker zieht, gehen die RAM-Inhalte aber verloren und beim nächsten Start wird wieder die ursprüngliche Konstante dorthin geladen. |
Member since May 2011
109 posts
|
![]()
@morty
Da hab ich mal was im Zusammenhang mit Druckern gehört: kleiner Link @sicherha: Aha, man schreibt also nicht direkt in den ROM |
Member since May 2011
331 posts
|
![]()
Also es gib auf den Meisten uC
|
Member since Oct 2012
31 posts
|
![]()
Die Übergabesemantik für
Zeiger als Funktionsparameter ist call-by-reference. ❏ Ein Zeiger kann zur Manipulation vonschreibgeschützten Datenbereichen ver-wendet werden. ❏ Zeiger vom Typ void* sind am besten für Zeigerarithmetik geeignet, da Sie kompatibel zu jedem Zeigertyp sind. Dann muss die Lösung wohl 1. sein, denn call-by-value sind die Zeiger sicher nicht. Nur die 3. Frage verstehe ich nicht ganz, was soll diese überhaupt heißen ? Zeiger zeigen doch auf Adressräume, also warum bräuchte ich void* ? Zudem noch eine Frage dazu : int *foo() { static int bar = 0; bar++; return &bar; } Gibt es hier irgendeinen Übersetzungsfehler, den ich evtl. nicht sehe? Dann ist dazu die richtige Lösung : "Die Variable bar ist über die Laufzeit derfoo()-Funktion hinaus gültig. Daher kann der zurückgelieferte Zeiger sicher vom Aufruferverwendet werden." Bar ist zwar lokal, aber static und somit über die gesamte Programmlaufzeit vorhanden. |
Member since May 2011
79 posts
|
![]()
Was passiert, wenn du einen als Parameter übergebenen Zeiger selbst (nicht dereferenzieren!) in einer Funktion veränderst? Hat das Auswirkung auf den Aufrufer?
Hm, ich versteh deine Rückfrage dazu nicht... Was genau ist unklar? |
Member since Oct 2012
31 posts
|
![]()
Ok, habe das mit den Zeigern verstanden, habe es damit durcheinandergeworfen, dass man Zeiger verwenden kann um call-by-reference nachzubilden.
Zu Zweiterem ist meine Frage, warum ich den Typ eines Zeigers überhaupt als void* definieren sollte. |
Member since May 2011
331 posts
|
![]()
Das wird dann verwendet wenn dein Zeiger auf einem Block Speicher zeigt, wo es aber egal - bzw nicht bekannt ist, was da drin steht. malloc gibt dir zum Beispiel einen Block Speicher, weiß aber nicht was du da reinschreiben willst. Anderes Beispiel wäre eine Verschlüsselungsfunktion. Der würde man einen void-Pointer und eine Länge geben. Was da drin steht - ob das jetzt eine Zeichenkette oder eine Struktur oder was auch immer ist, ist der Funktion selber egal. |
Powered by the Unclassified NewsBoard software, 20110527-dev,
© 2003-8 by Yves Goergen