void Zeiger - Frage



  • Hi ihr emsigen Coder 🙂 !

    Ich lern seit ner Weile C/C++ und hätte da ne Frage zum void-Zeiger. Was passiert, wenn ich einen void-Pointer auf eine Variable bestimmten Typs zeigen lasse, einen TypeCast nach long int* durchführe und dann Dereferenzierenderweise etwas an die entsprechende Speicheradresse schreibe?

    Wenn der Original-Datentyp größer gleich long int (je nach System unterschiedlich, meinetwegen 4 Bytes) ist dürfte es keine Probleme geben, aber was ist, wenn der Original-Datentyp kleiner ist? Dann könnte es doch sein, dass ich durch Zugriff über den void-Pointer Bits manipuliere, die gar nicht zu der Variable gehören, oder? Beispiel:

    <TYPEso-und-so> b = ...;
    void * pointer = &b;
    *((long int*)pointer) >> 1;
    

    Sagen wir, b belegt ein Byte Speicherplatz und hat anfangs den Wert 0x10001000, könnte folgendes passieren?

    ***andereVariablen***[u]bbbbbbbb[/u]***andereVariablen***...
    100100101010010100100[u]10001000[/u]100010100001010010100...
    Bitshift um eins nach rechts:
    ***andereVariablen***[u]bbbbbbbb[/u]***andereVariablen***...
    100100101010010100100[u]01000100[/u]010001010000101001010...
                                 ^ hier würden durch den Shift andere Variablen verändert
    

    Oder verhindert C/der Compiler/das System das irgendwie?

    Thx in advance,

    Red*Star



  • bestimmt nichts wohl definiertes



  • C verhinderts leider nicht. Aber C++ Compiler sollten ein implizites Casting von void* auf anderen Datentyppnt. nicht zulassen.

    Deswegen musst du es explizit machen (mit den Klammern) bzw. reinterpret_cast.
    Damit sagst du dem Compiler : Ich weiß was ich tue. Meine Verantwortung.



  • Hm, es gab da nämlich bei uns diese Aufgabe in einer der letzten Info-Klausuren, man solle Code schreiben, der bestimmte Bits einer float-Variable auf 0 setzt - und zwar gerade durch das oben beschriebene Procedere.

    In diesem Sinne: Es ist dann wohl besser, vorher die Typen zu prüfen und zu schauen, ob das mit den Größen hinhaut.

    @SeppSchrot: "Aber C++ Compiler sollten ein implizites Casting von void* auf anderen Datentyppnt. nicht zulassen."
    Hm, was für einen Sinn hat dann noch der void-Zeiger in C++? Da nimmt's man doch besser gleich von Anfang an den Zeiger passenden Datentyps, oder?

    Red



  • Erstmal sollte C++ so kompatibel zu C wie möglich sein.

    Die andern Gründe hab ich vergessen.



  • in void* kann man jede adresse reinstecken, typ ist egal
    beispiel:

    void f (void *p)
    {
     ...    
    }
    
    ...
    int x;
    float y;
    f (&x);   // geht
    f (&y);   // geht
    f (100);  // geht auch, aber nur in c
    ...
    


  • Red*Star schrieb:

    Oder verhindert C/der Compiler/das System das irgendwie?

    Ja es wird normalerweise verhindert, aber nicht so wie du das möchtest sondern durch eine AccessViolation.

    Nehmen wir mal folgendes Beispiel:

    char b = 0;
    void * pointer = &b;
    *((short*)pointer) >> 1; // geht: Der Inhalt vom Pointer wird nicht verändert
    *((short*)pointer) >>= 1; // geht nicht: Wir würden ein Byte hinter dem char auch verschieben
    
    unsigned int c = 0; 
    pointer = &c;
    *((short*)pointer) >>= 1; // geht, int > short
    


  • @Fireflow:

    *((short*)pointer) >>= 1; // geht nicht: Wir würden ein Byte hinter dem char auch verschieben
    

    Das ist ja gerade der Punkt: "Weiß" das System zum Zeitpunkt des Verschiebens und Neu-Zuweisens noch, dass der Pointer /eigentlich/ auf eine char-Variable zeigt? Denn eigentlich enthält der Pointer, da er void ist, doch nur eine einzige Information: Die Zieladresse. Nicht die Länge.

    Wenn ich den Zeiger also manuell auf short* caste, müsste das System denken: "Aha, ich bin im Speicher an Stelle xy, und soll ab hier die nächsten (sizeof(short) * 😎 Bits nach rechts schieben. Womit es zwar in einen nicht zur von mir gewünschten Variable zugehörigen Speicherbereich reinschreibt, es das aber überhaupt nicht interessieren sollte, weil ich ihm ja die Länge des Verschiebeblocks vorgebe.
    Weshalb es keine AccessViolation geben sollte, sondern unter Umständen irgendwelche "ver-rückten" (im wahrsten Sinne des Wortes) andere Variablen.

    MfG

    Red



  • Red*Star schrieb:

    Das ist ja gerade der Punkt: "Weiß" das System zum Zeitpunkt des Verschiebens und Neu-Zuweisens noch, dass der Pointer /eigentlich/ auf eine char-Variable zeigt?

    nö, wenn du den type cast davor setzt ist dem compiler das egal.


Anmelden zum Antworten