PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zeigerproblem



BLUESCREEN3D
30-05-2003, 04:34
folgender Quelltext:


#include <stdio.h>
#include <string.h>

int main()
{
char *pointer1;
pointer1=new char[4];
strcpy(pointer1,"123");
puts(pointer1);
*(pointer1+2)=0;
puts(pointer1);

char *pointer2="xyz";
puts(pointer2);
*(pointer2+2)=0;
puts(pointer2);

return(0);
}

gibt nach einer Kompilierung mit "g++ -o test test.cpp" folgende Ausgabe:


123
12
xyz
Speicherzugriffsfehler

Warum kann ich bei pointer1 den Inhalt ändern und bei pointer2 nicht???

SeeksTheMoon
30-05-2003, 11:54
im ersten Fall ist es ein Zeiger auf ein char-Array und im zweiten Fall ist es ein Zeiger auf eine Konstante Zeichenkette, deshalb kannst Du im zweiten Fall nicht an der Zeichenkette manipulieren.

BLUESCREEN3D
30-05-2003, 17:03
Trotzdem liegt die konstante Zeichenkette noch im RAM und ich finde es etwas komisch, dass ich den Inhalt von meinen RAM nicht ändern darf...

SeeksTheMoon
30-05-2003, 18:11
Ich zitiere:

"Konstante Werte werden bei der Übersetzung durch den Compiler hartcodiert, d.h. die Werte sind nicht irgendwo im Speicher abgelegt, von wo sie bei Bedarf ausgelesen werden können, sondern die Werte stehen direkt in den betreffenden Maschinenbefehlen" (C/C++ New Reference, S.99)

jetzt klar?

BLUESCREEN3D
31-05-2003, 21:20
Ich dachte immer, dass Programme, die man startet erstmal komplett in den RAM kopiert werden und von da aus ablaufen :confused:

Jasper
31-05-2003, 23:44
Original geschrieben von BLUESCREEN3D
Ich dachte immer, dass Programme, die man startet erstmal komplett in den RAM kopiert werden und von da aus ablaufen :confused:

das ist ja auch richtig. es gibt im protected mode aber verschiedene typen von speichersegmenten, sogenannte sections, z.b. .text, .data, .bss, etc.

die sections können geschützt werden, z.b. .text vor dem überschreiben.
wenn man es trotzdem versucht, wird ein sigsegv ausgelöst. genau das passiert in deinem beispiel.

-j

cyneox
04-06-2003, 14:57
was heisst denn die werte werden nicht im RAM gespeichert????
wenn man ein integer z.B. deklariert dann wird dieser integer über die so genannten speicherzellen aufgerufen...
beim zeiger ist fast das selbe :wenn der wert,auf den der zeiger zeigt,augegeben werden soll,dann wird zunächst die speicheradresse dieses zeigers ermittelt und dann den wert ,auf den der zeiger zeit,ausgegeben....

Jasper
04-06-2003, 15:02
Original geschrieben von cyneox
was heisst denn die werte werden nicht im RAM gespeichert????
wenn man ein integer z.B. deklariert dann wird dieser integer über die so genannten speicherzellen aufgerufen...
beim zeiger ist fast das selbe :wenn der wert,auf den der zeiger zeigt,augegeben werden soll,dann wird zunächst die speicheradresse dieses zeigers ermittelt und dann den wert ,auf den der zeiger zeit,ausgegeben....

worauf bezieht sich dein posting? mir fehlt da irgendwie ein zusammenhang.

-j

SeeksTheMoon
04-06-2003, 15:14
Du musst es auf Assembler-Ebene sehen. Die statischen Werte werden als Maschinenbefehle einprogrammiert und die stehen in einem bestimmten Segment.
Es gibt ja Stacksegment, Datensegment und so weiter.
Man kann mit Zeigern nicht beliebig irgendwo rumfuschen, sondern nur im Segment, in dem die Variablen liegen.
Die statischen Werte sind fester Programmcode, Du kannst mit einem Zeiger ja nicht den Verlauf des Programmes beeinflussen, also z.B. auf eine jne, mov oder sonstige Anweisung zeigen und diese verändern (außer durch einen Angriff auf Sicherheitslücken im Programm).
Deshalb kommt ein Segfault vom System. So hat es Jasper ja auch gesagt.

Alles klar?

pik7
04-06-2003, 16:15
hallo,

das mit den Maschinenbefehlen ist so nicht richtig.
Man kann ja die normalen Stringfunktionen drauf anwenden.
Wenn die werte dierekt in die Register geladen würden
könnte man das nähmlich nicht mehr.
Ist eher so das das Array im Text-Segment abgelegt wird
und das ist Read-only.

aus Herold/C Kompakt Referenz:

char *zeig = "abc";

Hier wird zeig als char-Zeiger definiert, der auf ein Array von Char mit der Länge 4
zeigt. Wird zeig verwendet, um den Inhalt dieses Arrays zu verändern, liegt ein
undefieniertes Verhalten vor. Dem Compiler ist es nähmlich erlaubt, solche Zeichenketten
in den Read-only-Speicher unterzubringen.

Ist also auch noch vom Compiler abhähngig.
Beim einen gehts beim andern nicht.

gruß

BLUESCREEN3D
05-06-2003, 14:25
@cyneox: worauf bezieht sich dein posting? mir fehlt da irgendwie ein zusammenhang.
mir auch


Du musst es auf Assembler-Ebene sehen. Die statischen Werte werden als Maschinenbefehle einprogrammiert und die stehen in einem bestimmten Segment.
Es gibt ja Stacksegment, Datensegment und so weiter.
Man kann mit Zeigern nicht beliebig irgendwo rumfuschen, sondern nur im Segment, in dem die Variablen liegen.
Die statischen Werte sind fester Programmcode, Du kannst mit einem Zeiger ja nicht den Verlauf des Programmes beeinflussen, also z.B. auf eine jne, mov oder sonstige Anweisung zeigen und diese verändern (außer durch einen Angriff auf Sicherheitslücken im Programm).
Deshalb kommt ein Segfault vom System. So hat es Jasper ja auch gesagt.

Alles klar?
jetzt wäre mir alles klar, wenn nicht der nächste post alles wieder dementieren würde *gg*

aber es kann gut sein, dass das vom compiler abhängig ist - werde das nachher mal ausprobieren

SeeksTheMoon
05-06-2003, 15:00
eigentlich nicht:
Read-Only bedeutet ja auch nur, in ein schreibgeschütztes Segment.

Auf jeden Fall ist dieser Code nicht ganz koscher. Mal sehen ob ich noch woanders was dazu finde.

cyneox
06-06-2003, 13:31
Original geschrieben von Jasper
worauf bezieht sich dein posting? mir fehlt da irgendwie ein zusammenhang.

-j

ein zusammenhang???jemand hat da geschrieben dass die daten nicht in den RAM oder im RAM gespeichert werden....das war eigentlich mein widerspruch