Not logged in. · Lost password · Register

Page:  1  2  next 
qa03sehu
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.
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
Sind sie dann schreibgeschützt?
sicherha
Informatik-Veteran
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:
  • Auf einfachen Mikrocontrollern wie dem AVR geschieht gar nichts, der Schreibzugriff wird einfach ignoriert.
  • Auf einem normalen Rechner wird der Prozessor den ungültigen Zugriff abfangen und an das Betriebssystem melden. Dieses schießt den verursachenden Prozess in der Regel ab.
Christian St.
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?
morty
SPiC-Meister
(Moderator)
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.
sicherha
Informatik-Veteran
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! :-D

... Und deswegen will man sich nicht auf irgendwelche kranken Hacks verlassen, sondern immer bewusst sauber programmieren. ;-)
il66ifix
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
 }
}
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
Quote by il66ifix:
heißt das, man könnte doch irgendwie einen Zähler basteln, der zählt, wie oft man den µC eingeschaltet hat??

Wie kommst du zu dieser Schlussfolgerung? (Ja, kann man, aber auch das ist aufwendiger und geht über den Stoff von SPiC hinaus).
This post was edited on 2012-03-21, 14:56 by morty.
sicherha
Informatik-Veteran
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.
il66ifix
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
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
Also es gib auf den Meisten uC
  • Flash-Speicher: Wird für das Programm verwendet. Ist nur von extern oder mit etwas Aufwand beschreibbar (wie genau steht in der Wikipedia, sowie dem AVR Datenblatt).
  • SRAM: Flüchtiger Arbeitsspeicher für die Variablen.
  • EEPROM Nicht flüchtiger Speicher. Mit weniger Aufwand zu beschreiben als der Flash.
Wie das mit den Variablen funktioniert wird auch in Kapitel 16 erklärt.
King-Chris
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.
This post was edited on 2013-07-17, 14:07 by King-Chris.
Raim
GSPiC-Guru
Member since May 2011
79 posts
Quote by King-Chris:
Dann muss die Lösung wohl 1. sein, denn call-by-value sind die Zeiger sicher nicht.

Was passiert, wenn du einen als Parameter übergebenen Zeiger selbst (nicht dereferenzieren!) in einer Funktion veränderst? Hat das Auswirkung auf den Aufrufer?

Quote by King-Chris:
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* ?

Hm, ich versteh deine Rückfrage dazu nicht... Was genau ist unklar?
King-Chris
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.
morty
SPiC-Meister
(Moderator)
Member since May 2011
331 posts
Quote by King-Chris:
Zu Zweiterem ist meine Frage, warum ich den Typ eines Zeigers überhaupt als void* definieren sollte.

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.
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O :troll:
Special characters:
Page:  1  2  next 
Go to forum
Powered by the Unclassified NewsBoard software, 20110527-dev, © 2003-8 by Yves Goergen