const char* Parameter -> Zugriffsverletzung
-
Hallo zusammen,
tut mir leid, dass ich das Forum im moment etwas vollspamme, aber dafür ist es ja da...Habe gerade ein Phänomen entdeckt, was mir vorher noch nie aufgefallen ist:
Blub PROC ;(const char* String) mov byte ptr [RCX], 0h Blub ENDP
char abc[] = "abc"; Blub(abc); //OK Blub("abc"); //Zugriffsverletzung
Woran liegt das?
Darf der Speicher bei der letzen Variante nicht beschrieben werden?
Falls ja, warum?
Ich hätte gedacht, dass beide Varianten im Prinzip gleich sind, da in beiden Fällen ein String ("abc") angelegt wird und anschließend seine Addresse per RCX an die Funktion übergeben wirdGruß
-
__username schrieb:
Darf der Speicher bei der letzen Variante nicht beschrieben werden?
Richtig.
Schreibzugriffe auf Stringliterale sind UB.
Deshalb auch die Deklaration als const.
-
UB, steht wofür?
Das heißt also, dass ich den String, wenn ich ihn manipulieren möchte, erst kopieren muss?
Gibts ne Möglichkeit in der aufgerufenen Funktion festzustellen, welche Art der Übergabe gewählt worden ist, um zu wissen, ob man den String ohne Zugriffsverletzung verändern darf?
Und warum ist
char c[] = "aaa"; Blub(c);
nicht gleich
Blub("aaa");
?
Weil wie gesagt, ich hätte gedacht das würde auf´s Gleiche hinauslaufen...
-
Bei
Blub("aaa")
legt der Compiler die Zeichen "aaa" im Speicher ab und markiert sie als "read only"
Bei
char c[] = "aaa";
Blub(c);erzeugste du ja ein Array of char das du dann mit "aaa" belegst . Dies ist mit Sicherheit nicht als "read only" markiert. Würde ja dann nichts bringen.
Nach meinem Wissen werden solche "Const"-Sachen im Bereich der Resorcen abgelegt.
Ein Beisp.
Wenn man mit dem Vizzard eine "Hallo Weld" App bosselt so legt der Vizzard den App-Namen in der Res.Datei ab.
Mittels
TCHAR szTitle[MAX_LOADSTRING];
wird ein Array für den Namen gemacht.
Und MittelsLoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
in das Arry geladen.
-
Ah, okay, danke
Gibts ne Möglichkeit in der aufgerufenen Funktion festzustellen, welche Art der Übergabe gewählt worden ist, um zu wissen, ob man den String ohne Zugriffsverletzung verändern darf?
Aber hat da vllt auch noch jemand ne Lösung?
-
Ich weis nicht ob mann mit "Try/Catch" so einen Fehler abfangen kann.
try
{
Blub("aaa");
}
catch (...)
{// Oh Shit
}
-
Hm... okay stimmt, man könnte nen ExeptionHandler doch sicher einrichten...
Danke
-
-
__username schrieb:
Blub PROC ;(const char* String) mov byte ptr [RCX], 0h Blub ENDP
Da fehlt aber ein entscheidender Befehle.
-
Du meinst "ret"?
Sollte ja nur mein Anliegen veranschaulichen@gargyle:
Sollte dann aber schon für Assembler sein
-
Der Link war nur damit __username sieht was gemeint ist.
Für asembler wirds das bestimmt in änlicher Form geben.
-
Egal ob
char c[] = "aaa"; Blub(c);
oder
char *c = "aaa"; Blub(c);
oder
const char *c = "aaa"; Blub(c);
ein C-Compiler erzeugt immer einen Zeiger, der auch als solcher innerhalb der Funktion verwendet wird.
Bliebe also nur noch der Unterschied zwischenvoid Blub(const char*s); void Blub(char*s);
zu klären, da schaust du dir den ASM Output deines Compilers an, in C gibt es dafür keine "Erkennungsmöglichkeit".
UB steht für undefined behavior, also undefiniertes Verhalten und ist ein mit C eingeführter Fachbegriff um anzuzeigen, dass der Compiler in diesem Fall Code produziert, dessen Resultat "beliebig" sein kann, in diesem Fall also, dass eine Änderung eines Stringliteralelements zu "beliebigen" Ergebnissen führen kann und dazu gehört auch, dass zur Compile- oder Laufzeit KEIN Fehler geworfen wird.
Der Zeiger auf das Stringliteral selbst kann in der Funktion aber natürlich auch geändert werden.
-
Vielen dank!