Nicht angemeldet. · Kennwort vergessen · Registrieren

Seite:  1  2  nächste 
qa03sehu
Mitglied seit 07/2011
1 Beitrag
Betreff: 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)
Mitglied seit 05/2011
331 Beiträge
Sind sie dann schreibgeschützt?
sicherha
Informatik-Veteran
Mitglied seit 10/2010
53 Beiträge
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. (Moderator)
Mitglied seit 05/2011
197 Beiträge
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)
Mitglied seit 05/2011
331 Beiträge
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
Mitglied seit 10/2010
53 Beiträge
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
Mitglied seit 05/2011
110 Beiträge
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)
Mitglied seit 05/2011
331 Beiträge
Zitat von 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).
Dieser Beitrag wurde am 21.03.2012, 15:56 von morty verändert.
sicherha
Informatik-Veteran
Mitglied seit 10/2010
53 Beiträge
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
Mitglied seit 05/2011
110 Beiträge
@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)
Mitglied seit 05/2011
331 Beiträge
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
Mitglied seit 10/2012
31 Beiträge
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.
Dieser Beitrag wurde am 17.07.2013, 15:07 von King-Chris verändert.
Raim
GSPiC-Guru
Mitglied seit 05/2011
79 Beiträge
Zitat von 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?

Zitat von 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
Mitglied seit 10/2012
31 Beiträge
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)
Mitglied seit 05/2011
331 Beiträge
Zitat von 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.
Schließen Kleiner – Größer + Auf diesen Beitrag antworten:
Prüfcode: VeriCode Gib bitte das Wort aus dem Bild ins folgende Textfeld ein. (Nur die Buchstaben eingeben, Kleinschreibung ist in Ordnung.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O :troll:
Weitere Zeichen:
Seite:  1  2  nächste 
Gehe zu Forum
Powered by the Unclassified NewsBoard software, 20110527-dev, © 2003-8 by Yves Goergen