Speicherzugriffsfehler char*
-
#include <iostream> using namespace std; char *my_func(char *&strf){ // 1.) //---------------------------------------------- char *temp="Hallo Welt"; strf=temp; // funktioniert // 2.) //---------------------------------------------- cout<<strf[2]<<endl; // funktioniert // 3.) //---------------------------------------------- strf[2] = "A"; // Das geht nicht // Erhalte Speicherzugriffsfehler return strf; } int main(){ char *strh="Hallo"; cout<<strh<<endl; my_func(strh); cout<<strh<<endl; return 0; }Konkret geht es dabei um Funktionen wie z.B erase() oder replace() die die Stringfunktionalitäten der cpp-Strings auch für c-Strings bereitstellen.
-
Gideon schrieb:
...char test[] erzeugt keinen konstanten zeiger, sondern einen array. ein konstanter zeiger wäre char *const. was du eigentlich verwendest ist aber ein const char * bzw. char const *...
Ist ein Array (z.B. char str[20]; ) nicht auch ein konstanter Zeiger, da die Anfangsadresse nicht veränderbar ist?
Gruß
-
das stimmt. allerdings musst du zwischen konstanten zeigern und zeigern auf konstanten unterscheiden.
const char *foo; // du darfst den zeiger ändern, aber nicht den inhalt *foo = 0; // fehler foo = "foo"; // ok char *const bar; // du darfst den inhalt ändern, aber nicht den zeiger *bar = 0; // ok bar = "bar"; // fehlerso weit, so gut. aus irgendwelchen gründen erlaubt c/c++ nun aber dieses konstrukt
char *qux = "qux"; // "qux" ist const char *, wird aber implizit zu char * *qux = 0; // boom! der inhalt von qux darf nicht geändert werden, aber es kompiliert trotzdem!
-
du meintest
strf[2] = 'A'; // Das geht nicht
statt "A" nehme ich an.dann erhalte ich auch nen speicherzugriffsfehler.
mache ich dann
char temp[]="Hallo Welt";
draus, gehts.Hallo l HaAlo Weltes kommt nicht drauf an, daß die zeiger unveränderlich ist, sondern das das zeug, wo die zeiger draufzeigen unveränderlich ist.
-
Vielen Dank für die Antworten und das um diese Zeit.
Jetzt ist es mir klar geworden.Ist das mit der Typenumwandlung vom Compiler abhängig und aus
welchen Gründen wird diese vorgenommen?Danke!
Grüße
-
matko schrieb:
Vielen Dank für die Antworten und das um diese Zeit.
Jetzt ist es mir klar geworden.Ist das mit der Typenumwandlung vom Compiler abhängig und aus
welchen Gründen wird diese vorgenommen?Danke!
Grüßetypumwandlung? ka.
aber ich erzähl dir, warum stringliterale konstant sind.der compiler macht ja aus
char* hw="hello, world!";sowas wie
//irgendwo im speicher zum beispiel an adresse 0x4711 stehen die //datenbytes "hello, world!" char* hw=0x4711;die datenbytes stehen so in der exe-datei und werden beim starten in den speicher geladen.
dem compiler ist darüberhinaus erlaubt, aus
char* hw="hello, world!"; char* w="world!";ein pfiffiges
char* hw="hello, world!"; char* w=hw+7;zu machen. er faßt also strings zusammen, wenn es geht.
schreibst du jetzt
char* hw="hello, world!"; char* w="world!"; *w='W';dann haste BEIDE strings verändert.
um sowas zu vermeiden, liegen die strings am besten in einem speichersegment, das als schreibgeschützt markiert ist. zum beispiel dort, wo der ausführbare maschinencode des programms liegt, der sollte auch schreibgeschützt sein, das wäre ganz nett.wenn du aber mit char hw[]="hello, world"; ein array of char auf dem stack anlegst, gehört es dir ganz alleine und ist eine kopie des strings aus dem schreibgeschützen speicher. entsprechend muß es auch immer wieder angelegt werden, was ein bißchen zeit kostet, aber nicht viel.
-
matko schrieb:
Ist das mit der Typenumwandlung vom Compiler abhängig und aus
welchen Gründen wird diese vorgenommen?Das ist Abwärtskompatibilität zu C ("damals" galten String-Literale noch als char* - und um alte C-Programme in C++ weiternutzen zu können, wurde die Umwandlung eines (const char*) String-Literals nach char* im C++ Standard genehmigt).
PS: Ein Bonustip von mir: Nimm lieber std::string, da bist du auf der sicheren Seite.
-
CStoll schrieb:
PS: Ein Bonustip von mir: Nimm lieber std::string, da bist du auf der sicheren Seite.
mein tip: hör nicht drauf.
-
volkard schrieb:
CStoll schrieb:
PS: Ein Bonustip von mir: Nimm lieber std::string, da bist du auf der sicheren Seite.
mein tip: hör nicht drauf.
Was soll so eine scheiss Antwort? Begründung bitte!
-
Was hast du gegen std::string? Ehe ich mich mit der Speicherverwaltung und -Sicherheit rumschlage, verwende ich lieber eine Klasse, die das für mich erledigt.
-
CStoll schrieb:
Was hast du gegen std::string? Ehe ich mich mit der Speicherverwaltung und -Sicherheit rumschlage, verwende ich lieber eine Klasse, die das für mich erledigt.
mir scheint, matko arbeitet sich gerade toll in zeiger und so ein. ist das nicht wunderbar?
ok, klar soll er bei den meisten sachen umsteigen, kommt immer auf das programm an.
-
Danke für die echt ausfürlichen Antworten.
Natürlich ist das Arbeiten mit c++ strings einfacher, aber es gibt nunmal auch Vorgaben das man numr mit Zeigern arbeiten darf (durch den Prof z.B
).
Das Verstehen und Anwenden mit Zeigern mit den großen Möglichkeiten ist für mich von Interesse.Gruß & Thx
matko
-
matko schrieb:
Ist ein Array (z.B. char str[20]; ) nicht auch ein konstanter Zeiger
Nein, ist es nicht und wird es auch niemals sein. Ein Array ist nunmal kein Zeiger. Ein Compiler darf aber bei Bedarf ein Array in einen Zeiger auf das erste Element umwandeln. Dieser Zeiger kann, muss aber nicht konstant sein.