2017-01-06 1 views
0

Ich fand heraus, dass Adresse des ersten Elements der Struktur die gleiche wie die Adresse der Struktur ist. Die Dereferenzierung der Adresse der Struktur gibt jedoch nicht den Wert des ersten Datenelements zurück. Die Dereferenzierungsadresse des ersten Datenelements gibt jedoch seinen Wert zurück. z.B. Die Adresse der Struktur = 100, die Adresse des ersten Elements der Struktur ist ebenfalls 100. Nun sollte die Dereferenzierung bei beiden auf die gleiche Weise funktionieren.Dereferenzieren einer Struktur, um den Wert des ersten Mitglieds zu erhalten

Code:

#include <iostream> 
#include <cstring> 

struct things{ 
    int good; 
    int bad; 
}; 

int main() 
{ 
    things *ptr = new things; 
    ptr->bad = 3; 
    ptr->good = 7; 
    std::cout << *(&(ptr->good)) <<" " << &(ptr->good) << std::endl; 
    std::cout << "ptr also print same address = " << ptr << std::endl; 
    std::cout << "But *ptr does not print 7 and gives compile time error. Why ?" << *ptr << std::endl; 
    return 0; 
} 
+0

'* & some_type' sollten Sie immer' some_type' geben, solange Sie keine verrückten Überladen von Operatoren haben. – NathanOliver

+0

Wenn Sie einen Zeiger dereferenzieren, erhalten Sie den Wert dessen, worauf der Zeiger zeigt. Wenn der Zeiger auf eine Struktur zeigt, ist der "Wert" die * Struktur *. –

+0

Während die Adresse des ersten Mitglieds * die gleiche wie die Adresse der Struktur sein kann, ist ein Zeiger auf die Struktur * kein * Zeiger auf das erste Mitglied. Die Typen sind zunächst unterschiedlich. –

Antwort

0

Sie einen Abguss des Zeiger tun können, um STRUCT, auf einen Zeiger auf das erste Element der Struktur so dass der Compiler weiß, welche Größe und Ausrichtung zu sammeln zu verwenden der Wert aus dem Speicher. Wenn Sie einen "sauberen" Cast wünschen, können Sie ihn zuerst in "VOID pointer" umwandeln.
_ (Struct *) bis (VOID *) bis (FirstElem *) _
Siehe auch: Pointers in Stackoverflow
Hoffe, es hilft !!

+1

von 'X * 'zu sammeln 'void *' und dann zurück zu etwas anderem als 'X *' macht ein Programm schlecht geformt. –

+0

@RichardHodges Nicht, wenn Sie es richtig behandeln. Sogar Microsoft verwendet es in ihrem [Driver Development Framework Code] (https://github.com/Microsoft/Windows-driver-samples) –

+0

@Fernando: Weil Microsoft etwas im Code tut, bedeutet es nicht, dass es korrekt ist. Im Allgemeinen verstößt dies gegen strenge Aliasing-Regeln. Edit: Ich bin mir sicher, dass Microsoft es irgendwie richtig behandelt, indem es vor dem ersten Element keine Auffüllung in der Struktur erzwingt, es ist einfach keine gute Empfehlung, OP zu geben. – AndyG

0

*ptr gibt Ihnen eine Instanz des Typs things zurück, für die operator << nicht definiert ist, daher der Fehler bei der Kompilierung.

Eine Struktur ist nicht dasselbe wie ein Array . Das bedeutet, dass es nicht notwendigerweise zu einem Zeiger auf sein erstes Element zerfällt. Der Compiler ist tatsächlich frei (und tut es oft) insert padding in einer Struktur, so dass er an bestimmten Bytegrenzen ausgerichtet ist . Also sogar wenn ein struct könnte auf die gleiche Weise wie ein Array (schlechte Idee) verfallen, würde einfach Drucken es nicht garantieren, Drucken des ersten Elements!

meine ich eine C-Style-Array wie int[]

Diese Grenzen sind abhängig von der Implementierung und kann oft in irgendeiner Weise über Präprozessoranweisungen wie pragma pack

0
gesteuert werden

Ich fand heraus, dass die Adresse des ersten Elements der Struktur die gleiche wie die Adresse der Struktur ist.

Wo immer Sie das herausgefunden haben, war es nicht der C++ Standard. Es ist eine falsche Annahme im allgemeinen Fall.

Es gibt nichts als Elend und Schmerz für Sie, wenn Sie diesen Weg fortsetzen.

0

einem these Versuchen:

#include <iostream> 
#include <cstring> 

struct things{ 
    int good; 
    int bad; 
}; 

int main() 
{ 
    things *ptr = new things; 
    ptr->bad = 3; 
    ptr->good = 7; 

    std::cout << *(int*)ptr << std::endl; 
    std::cout << *reinterpret_cast<int*>(ptr) << std::endl; 

    int* p = reinterpret_cast<int*>(ptr); 
    std::cout << *p << std::endl; 
    return 0; 
} 
Verwandte Themen