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 wird 😮

    Gruß



  • __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 Mittels

    LoadString(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 zwischen

    void 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!


Anmelden zum Antworten