Zeiger auf irgendwas immer 4 Byte gross ?



  • Hallo,

    wenn ich folgende Programm ausführe:

    cout << sizeof(char*) << endl;
    	cout << sizeof(double*) << endl;
    	cout << sizeof(float*) << endl;
    	cout << sizeof(int*) << endl;
    	cout << sizeof(Test*) << endl;
    

    Gibt er mir uberall 4 Byte aus. Warum ist das so ich habe gedacht ein Zeiger auf irgendwas hat immer die gleiche grösse wie der Datentyp selsbt. z.B double = 8 Byte => double* = 8 Byte. Warum immer 4 Byte ?

    mfg
    🙂



  • nee, in einen zeiger muss 'ne adresse reinpassen. die ist auf deiner platform zufälligerweise 4 bytes gross. könnte woanders auch 2, 5 oder 9 bytes sein.



  • Mich hat das am Anfang auch verwirrt.
    Vergiss das mit dem zeigen.
    Ein Zeiger ist einfach eine Variable, in der eine Adresse gespeichert wird.
    Und es gibt anscheinend maximal so viele verschiedene Adressen, wie in 4 Bytes reinpassen.
    Die verschiedenen Arten von Zeigern sind nur beim Dereferenzieren von Bedeutung.

    Was mich mal interessiert:
    Was passiert denn, wenn es irgendwann Computer gibt, mit einem so großen Arbeitsspeicher, dass 4 Bytes nicht mehr reichen? Funktionieren dann die alten Programme nicht mehr?
    Oder hat das gar nichts damit zu tun?



  • Es gibt Plattformen mit anderen Größen, z.B. 64 Bit Systeme sind nichts neues, da ist ein Zeiger entsprechend größer.



  • Außerdem muss nicht jeder Zeiger 4Byte groß sein.

    Könnt ja mal spaßeshalber folgendes testen:

    #include <iostream>
    
    class Base
    {
      public:
        virtual void doIt() = 0;
    };
    
    class Derived : public virtual Base
    {
      public:
        void doIt(){}
    };
    
    int main()
    {
       std::cout << sizeof( &Derived::doIt );
    }
    


  • obbba schrieb:

    Was mich mal interessiert:
    Was passiert denn, wenn es irgendwann Computer gibt, mit einem so großen Arbeitsspeicher, dass 4 Bytes nicht mehr reichen? Funktionieren dann die alten Programme nicht mehr?

    wenn im programm irgendwo die grösse eines zeigers gebraucht wird, dann nimm 'sizeof()' und keine fixe zahl. dann klappt das schon...
    :xmas2:



  • Ein normaler Zeiger auf DATEN ist im Normalfall immer gleich gross.
    Funktionszeiger und Member-Zeiger sind wieder eine andere Geschichte.



  • hustbaer schrieb:

    Ein normaler Zeiger auf DATEN ist im Normalfall immer gleich gross.

    ...und was ist für dich der normalfall?


  • Mod

    Grundsätzlich können verschiedene Pointertypen verschiedene Größen haben. Das wird nur dadurch eingeschränkt, dass Pointer, deren Pointee sich nur durch cv-Qualifikation (evtl. auch nur in höheren Indirektionsebenen) unterscheiden dieselbe Representation haben. Gleichermaßen sind char* und void* identisch hinsichtlich der Representation. Mir ist allerdings kein Compiler bekannt, der das tut (mein Erfahrungshorizont ist aber auch sehr beschränkt). Ein Hinweis im Standard ist der, dass die Umwandlung eines Pointers in einen anderen dann undefiniertes Verhalten ist, wenn die Alignmentvoraussetzungen des Zielpointers größer sind und das Argument nicht gerade durch vorherige Umwandlung des Zielpointers in das Argument entstanden ist. Beispiel: Unsere Maschine möge eine Wortbreite von 32bit haben, d.h. hardwareseitig sind nur 32bit Wörter direkt adressierbar. Unser Compiler soll allerdings für char trotzdem nur 8bit benötigen. Ein char pointer würde dann intern etwa so aufgebaut sein:

    struct char_pointer
    {
        native_pointer p;
        unspecified select : 2;
    }
    

    wir benötigen also noch zwei zusätzliche bit, um das jeweilige char zu ermitteln. Für Datentypen mit einem Alignment von 4 (also z.b. ein 32bit int auf dieser Plattform) sind diese zusätzlichen Bit allerdings unnötig, Der Compiler könnte einen int-Zeiger unmittelbar auf den hardwareseitig unterstützten Pointer abbilden. Nun ist aber klar, dass bei der Umwandlung eines char* in ein int* auf dieser Plattform Information verlorengeht.
    Aus Sicht der Implementation wird das Ganze aber extrem problematisch, wenn unvollständige Datentypen (abgesehen von void) ins Spiel kommen. Beispiel:
    ÜE1:

    struct T { char x; };
    struct U { int y; };
    
    U* cast(T* p);
    
    void foo()
    {
        T* p = ...
        U* q = cast( p );
        // ...
    }
    

    ÜE2:

    struct T;
    struct U;
    
    U* cast(T* p) { return reinterpret_cast< U* >( p ); }
    

    Der Compiler wird in der Funktion cast die genaue Representation von T* und U* kennen müssen, um Code zu erzeugen. T und U sind aber dort unvollständig. Das ist ein Problem wenn getrennt übersetzt wird und die Pointerrepräsentation vom Typ des Pointees abhängt.



  • @lolz

    dein code gibt bestimmt nicht die größe eines Zeigers aus mit & werden referenzen angegeben oder addresse eines objekts zurückgegeben.Zeiger werden mit * gekennzeichnet.



  • walljumper schrieb:

    @lolz

    dein code gibt bestimmt nicht die größe eines Zeigers aus mit & werden referenzen angegeben oder addresse eines objekts zurückgegeben.Zeiger werden mit * gekennzeichnet.

    Wenn man keine Ahnung hat...



  • dann erklärs mir



  • &foo ist ein Zeiger auf foo.



  • sorry aber bei mir ist foo* ein Zeiger &foo gibt bei mir die addresse von foo zurück.



  • walljumper schrieb:

    sorry aber bei mir ist foo* ein Zeiger

    Nein, das ist ein Syntaxfehler (foo ist eine Variable, eine Funktion, etc. - kein Typ!)

    &foo gibt bei mir die addresse von foo zurück.

    Und das ist was anderes als ein Zeiger???



  • Nein, das ist ein Syntaxfehler (foo ist eine Variable, eine Funktion, etc. - kein Typ!)

    du hast nicht geschrieben was foo ist ^^

    naja ne addresse ist für mich schon was anderes als ein Zeiger ne addresse ist ein Wert. Ein Zeiger eine Variable die einen Wert enthält.



  • SG1 schrieb:

    &foo gibt bei mir die addresse von foo zurück.

    Und das ist was anderes als ein Zeiger???

    ist es:

    int *p = &intvariable; // links ist ein zeiger, rechts ist eine adresse
    

    :xmas2:



  • walljumper schrieb:

    Nein, das ist ein Syntaxfehler (foo ist eine Variable, eine Funktion, etc. - kein Typ!)

    du hast nicht geschrieben was foo ist ^^

    Hallo? Kontext? Versteht sich ja wohl von selbst, dass ich mich auf den Beitrag von lolz bezogen hab.



  • also erstmal:

    ein Zeiger ist eine Variable und speichert NICHT irgendeinen Wert, sondern IMMER eine Adresse.
    Dabei ist der Typ völlig unbedeutend, ein Zeiger ist immer gleich groß, zumindest auf der gleichen Plattform.
    So ist zum Beispiel ein Zeiger im Real-Mode des Prozessors IMMER 16 Bit
    (2 Byte) groß.
    Im Protected-Mode, wo auch Win32 arbeitet, ist jeder Zeiger 32 Bit (4 Byte) groß.
    Und bei 64 Bit-Windows, was logischer Weise nur auf einem Prozessor mit 64 Bit laufen kann, wird ein Zeiger IMMER 64 Bit oder 8 Byte groß sein.

    Wer mehr dazu wissen möchte, sollte sich mit Assembler befassen, da wird einem das ganze erklärt.

    MfG DrakoXP



  • DrakoXP schrieb:

    ein Zeiger ist immer gleich groß, zumindest auf der gleichen Plattform.

    falsch.


  • Mod

    DrakoXP schrieb:

    also erstmal:

    ein Zeiger ist eine Variable und speichert NICHT irgendeinen Wert, sondern IMMER eine Adresse.
    Dabei ist der Typ völlig unbedeutend, ein Zeiger ist immer gleich groß, zumindest auf der gleichen Plattform.
    So ist zum Beispiel ein Zeiger im Real-Mode des Prozessors IMMER 16 Bit
    (2 Byte) groß.
    Im Protected-Mode, wo auch Win32 arbeitet, ist jeder Zeiger 32 Bit (4 Byte) groß.
    Und bei 64 Bit-Windows, was logischer Weise nur auf einem Prozessor mit 64 Bit laufen kann, wird ein Zeiger IMMER 64 Bit oder 8 Byte groß sein.

    Wer mehr dazu wissen möchte, sollte sich mit Assembler befassen, da wird einem das ganze erklärt.

    MfG DrakoXP

    Was ist ein Fensters?
    Komisch, dass mir unter DOS ständig 4Byte-Far-Pointer über den Weg gelaufen sind...

    Was irgendein assembler zum Thema Pointer zu sagen hat, ist in C++ (zunächst) völlig irrelevant. Und wie bereits erwähnt, es gibt nur beschränkte Garantien. Im Übrigen sollten solche Unterschiede bei sauberer Programmierung keinen Unterschied machen. Funktioniert etwas bei veränderter Größe plötzlich nicht mehr, dürfte dem in 99% aller Fälle von vornherein ein Logikfehler zugrunde liegen.


Anmelden zum Antworten