Pointer, Objekte, Speicherdarstellung



  • hi,

    hab n paar Fragen zum casten von Pointern, und Darstellung von Objekten im Speicher.

    Erstmal zu dem Pointern:
    Hab jetzt durch rumprobieren herausgefunden, dass bei nem cast von int* auf char* der char Pointer auf die letzte Speicherstelle des ints zeigt

    Int im Speicher

    +----+----+----+----+
    |  20|  21|  22|  23|   Adresse
    +----+----+----+----+
    

    Also würde hier der Zeiger die Adresse 23 sein, und nicht 20?

    Wie verhält sich das bei Objekten, bzw Strukturen? Genauso oder wird zB auf das letzte Byte des 1. Elements gezeigt?

    Zu den Objekten:
    Wie genau werden Objecte im Speicher abgelegt?
    Ein Prog in meiner Uni meinte es weren alle Attribute gespeichert und ein pointer auf jeden Funktion + die Basisklasse

    zB

    int                 4 Byte   Adresse 20
    long long           8 Byte   Adresse 24
    Ptr Funktion 1      4 Byte   Adresse 32
    Ptr Funktion 2      4 Byte   Adresse 36
    Ptr Konstruktor     4 Byte   Adresse 40
    Ptr Destruktor      4 Byte   Adresse 44
    

    Also 28 Bytes im Speicher für jedes Objekt
    Ein Zeiger auf das Objekt würde dann auf Adresse 23 zeigen (1. Element im speicher hier mit 4 Byte)?

    Als ich aber von einer TestKlasse (siehe unten), kahm bei sizeof beide male 4 (Bytes) heraus, also nehme ich mal an, das is der int?
    Die Adresse auf eine Methode war 1 (&TestKlasse::Methode1 oder &TestKlasse::Methode2 beidemale 1) oO
    Soweit ich gelesen hab gibt die Adresse auf eine Methode den Abstand in Bytes vom Anfang des Objekts auf die Methode

    TestKlasse:

    class TestKlasse
    {
    private:
    	int i;
    public:
    	TestKlasse(int zahl) {
    		this->i = zahl;	}
    	void Methode1() {
    		cout << "Methode 1: " << i << endl; }
    	void Methode2() {
    		cout << "Methode 2: " << i+1 << endl; }
    };
    
    int main(void)
    {
    	TestKlasse tk(5);
    	cout << "TestKlasse:" << endl;
    	cout << "  sizeof  : " << sizeof(tk) << endl;
    	cout << "  methode1: " << &TestKlasse::Methode1 << endl;
    	cout << "  methode2: " << &TestKlasse::Methode2 << endl;
    }
    

    wäre super wenn mir jemand sagen könnte wie das so ist,
    oder wüsste wo man sowas anchlesen kann

    mfg



  • leb0rtran schrieb:

    hi,

    hab n paar Fragen zum casten von Pointern, und Darstellung von Objekten im Speicher.

    Erstmal zu dem Pointern:
    Hab jetzt durch rumprobieren herausgefunden, dass bei nem cast von int* auf char* der char Pointer auf die letzte Speicherstelle des ints zeigt

    Int im Speicher

    +----+----+----+----+
    |  20|  21|  22|  23|   Adresse
    +----+----+----+----+
    

    Also würde hier der Zeiger die Adresse 23 sein, und nicht 20?

    ja char* zeigt, so weit ich weiß, immer auf das niedrigste Byte eines int.
    Welche Addresse das Byte hat ist von Prozessor abhängig -> endianness

    Wie verhält sich das bei Objekten, bzw Strukturen? Genauso oder wird zB auf das letzte Byte des 1. Elements gezeigt?

    Der Pointer zeigt immer auf den Anfang.

    Zu den Objekten:
    Wie genau werden Objecte im Speicher abgelegt?
    Ein Prog in meiner Uni meinte es weren alle Attribute gespeichert und ein pointer auf jeden Funktion + die Basisklasse

    zB

    int                 4 Byte   Adresse 20
    long long           8 Byte   Adresse 24
    Ptr Funktion 1      4 Byte   Adresse 32
    Ptr Funktion 2      4 Byte   Adresse 36
    Ptr Konstruktor     4 Byte   Adresse 40
    Ptr Destruktor      4 Byte   Adresse 44
    

    Also 28 Bytes im Speicher für jedes Objekt
    Ein Zeiger auf das Objekt würde dann auf Adresse 23 zeigen (1. Element im speicher hier mit 4 Byte)?

    Als ich aber von einer TestKlasse (siehe unten), kahm bei sizeof beide male 4 (Bytes) heraus, also nehme ich mal an, das is der int?
    Die Adresse auf eine Methode war 1 (&TestKlasse::Methode1 oder &TestKlasse::Methode2 beidemale 1) oO
    Soweit ich gelesen hab gibt die Adresse auf eine Methode den Abstand in Bytes vom Anfang des Objekts auf die Methode

    TestKlasse:

    class TestKlasse
    {
    private:
    	int i;
    public:
    	TestKlasse(int zahl) {
    		this->i = zahl;	}
    	void Methode1() {
    		cout << "Methode 1: " << i << endl; }
    	void Methode2() {
    		cout << "Methode 2: " << i+1 << endl; }
    };
    
    int main(void)
    {
    	TestKlasse tk(5);
    	cout << "TestKlasse:" << endl;
    	cout << "  sizeof  : " << sizeof(tk) << endl;
    	cout << "  methode1: " << &TestKlasse::Methode1 << endl;
    	cout << "  methode2: " << &TestKlasse::Methode2 << endl;
    }
    

    wäre super wenn mir jemand sagen könnte wie das so ist,
    oder wüsste wo man sowas anchlesen kann

    mfg

    müsste alles implementierungsabhängig sein.


  • Mod

    Objekte speichern keine Pointer auf ihre Memberfunktionen.



  • Sondern übergeben ihren Methoden den impliziten this Zeiger auf den Anfang ihrer Daten.



  • irgendwer schrieb:

    Der Pointer zeigt immer auf den Anfang.

    Aber auf was für einen Anfang? Auf das 1. Element generell, oder auf das 1.Byte des kompletten structs?

    struct blaT {
      int bla;
      string xyz; };
    

    Angenommen der struct is 10Byte lang und geht von Adresse 20 bis 29, ist der Zeiger dann 20 (der Anfang des structs von den Bytes aus gesehen) oder ist der Zeiger 23 (Zeiger zeigt auf das 1. Element, was ein int ist, und bei einem int zeigt der Zeiger auf das letzte Byte)
    Da muss es doch eine einheitliche Regel geben?

    irgendwer schrieb:

    müsste alles implementierungsabhängig sein.

    OS bzw Compiler abhängig (oder gleich beides)?

    SeppJ schrieb:

    Objekte speichern keine Pointer auf ihre Memberfunktionen.

    blub² schrieb:

    Sondern übergeben ihren Methoden den impliziten this Zeiger auf den Anfang ihrer Daten.

    Also sieht das Objekt wie ein struct aus, also hier nur ein 4 Byte int

    Was sagt mir dann die Ausgabe "1" von &TestKlasse::Methode1 und bei &TestKlasse::Methode2, sollte ja dann entweder 1 und 2 oder 4 und 8 (in Bytes, 4Byte der int, 4 Byte der Pointer auf Methode1 und 4 Byte für Methode2)

    http://www.math.uni-wuppertal.de/~axel/skripte/oop/oop12_5.html schrieb:

    Vielmehr beschreiben sie (bei Pointern auf Datenmember) die Position des Members innerhalb der Klasse. Sie werden intern durch die Adreßdifferenz des Datenmembers zum Beginn des ganzen Objekts dargestellt



  • leb0rtran schrieb:

    Aber auf was für einen Anfang? Auf das 1. Element generell, oder auf das 1.Byte des kompletten structs?

    Im Allgemeinen schwer zu sagen, da es von vielen Dingen abhängen kann, dem Compiler, dem OS, ob grade ein Schaltjahr ist, usw.

    Als Beispiel für diesen ganzen Kram die Zahl einhundertdreiundzwanzig
    nehmen wir an, der Prozessor speichert jede Ziffern an einer eigenen Speicheradresse ab und grundsätzlich nur Zahlen die aus vier Ziffern bestehen. Dabei gibt es zwei Möglichkeiten:
    1. Er speichert die Ziffer mit der niedrigsten Wertigkeit in der niedrigsten Addresse

    |0x1|0x2|0x3|0x4|
    -----------------
    | 3 | 2 | 1 | 0 |
    

    2. Die Ziffer mit der höchsten Wertigkeit kommt in die niedrigste Addresse

    |0x1|0x2|0x3|0x4|
    -----------------
    | 0 | 1 | 2 | 3 |
    

    Zum Glück weiß der Compiler, wie welcher Prozessor das macht.
    Problematisch wird es nur wenn du binäre Daten zwischen den beiden Systemen tauscht.

    Da muss es doch eine einheitliche Regel geben?

    Nicht wirklich, der Standard sagt nur, wie so oft, wie es formal auszusehen hat und das es funktionieren soll. Zudem darf der Compiler beliebig viele 0 Bytes einfügen, um optimale Größen zuerreichen.



  • ich bin doch irgendwer


Anmelden zum Antworten