2016-06-23 8 views
2

ich das folgende einfache Testprogramm erstellt zu zeigen, dass ich die Adresse der öffentlichen integer können den Wert einer privaten integer zuzugreifen:Verwendung der Adresse eines öffentlichen Membervariable ein eigenes Mitglied zuzugreifen

#include <iostream> 
using namespace std; 
class CarType{ 
    public: 
    int year; 
    CarType(int price, int year){this -> year = year; this -> price = price;}; 
    private: 
    int price; 
}; 

int main(){ 
    //Create new CarType object 
    CarType a = CarType(15000, 1999); 
    //Increment the memory address of public member variable, year by 1 and save the result 
    int* pricePointer = &a.year+1; 
    //De-reference the memory address and output it 
    cout << "PRICE: "<< *pricePointer << endl; 
    return 0; 
} 

Die Ausgabe zeigt, dass ich auf die Preisvariable zugreifen kann, indem ich nur die Adresse des Jahres kenne. Gibt es einen Weg, dies zu verhindern? Ist das nur ein Randfall oder gilt das für alle Arten von Objekten?

+3

C++ wird nicht verhindern, dass jemand sich in den Fuß schießt. – songyuanyao

+1

Es gibt keine Garantie, dass das, was Sie tun, immer funktioniert. Im Wesentlichen hat der Compiler in diesem Fall den Speicher so ausgelegt, dass die Variable "price" unmittelbar nach "year" platziert wird. Da Sie jedoch eine Klasse und keinen POD verwenden und der Compiler dem Objekt "Sachen hinzufügt", gibt es keine Garantie dafür, dass der Speicher immer auf diese Weise angelegt wird. Versuchen Sie, andere Membervariablen und -methoden hinzuzufügen, und sehen Sie, was passiert. Siehe Punkt 11 von C++ - Allgemeinwissen von Stephen C. Dewhurst für Details. Andere, die mit den Compiler-Designs besser vertraut sind, könnten mehr Details zur Verfügung stellen. – lightalchemist

Antwort

3

Dies ist möglicherweise undefined (aber sicherlich unklug) Verhalten und Sie können es auf die gleiche Weise verhindern, wie Sie Menschen an zufällige Adressen schreiben, oder verhindern, unerfahrene Menschen mit einer Kettensäge Gliedmaßen abschneiden. Mit anderen Worten, überhaupt nicht.

Vorbehalt Coder.

Der Grund, warum ich sage möglicherweise in dem obigen Absatz ist, dass es nicht ganz klar ist. In sprach Anwalts Begriffe siehe C++14 5.7 Additive operators /4:

Für die Zwecke dieser Operatoren, ein Zeiger auf eine Nonarray Objekt verhält sich wie ein Zeiger auf das erste Element eines Array der Länge eines mit dem Typ des Objekt als Elementtyp.

und /5 wenn auf einen Zeiger Hinzufügen eines Integralwert Diskussion:

Wenn sowohl der Zeigeroperanden und das Ergebnis Punkt auf Elemente des gleichen Array-Objekt oder ein hinter dem letzten Element des Arrays Objekt, die Bewertung soll keinen Überlauf erzeugen; Andernfalls ist das Verhalten nicht definiert.

In Ihrem Fall zeigt Ihr Zeiger tatsächlich "eins nach dem letzten Element", so dass die Addition selbst kein undefiniertes Verhalten erzeugt.

Sie mögen denken, dass das Objekt dereferencing nicht definiert, sondern würde, nach einer Notiz in 3.9.2 Compound types /3, wie es scheint kann es gültig sein:

Zum Beispiel die Adresse einer über das Ende eines Arrays (5.7) würde in Betracht gezogen werden, auf ein nicht verwandtes Objekt des Elementtyps des Arrays zu zeigen, das sich möglicherweise an dieser Adresse befindet.

jedoch nicht definiert oder nicht, ist es noch zu dereferenzieren unklug, da Sie eigentlich gar nicht wissen, dass es dort eine Variable vom richtigen Typ ist. Implementierungen sind frei, Strukturen so zu puffern, wie sie es für richtig halten, also gibt es keine Garantie, dass price dasselbe ist wie *(year + 1).

+0

Könnte dies ein Sicherheitsproblem sein, wenn ich Zugriff auf den Quellcode der Bibliothek hatte, die ich gerade implementierte? (zB Eine schlecht geschriebene Passwort-Validierungsfunktion) – isquaredr

+2

@isquardr [Ist Encapsulation ein Sicherheitsgerät?] (https://isocpp.org/wiki/faq/classes-and-objects#encap-is-not-security) – PaulMcKenzie

+1

@isquaredr Das wäre ein viel größeres Problem, wenn Sie keinen Zugriff auf den Quellcode der Bibliothek hätten, die ich implementiert habe. Ich denke, Sie müssen herausfinden, worüber Sie sich Sorgen machen könnten. – dxiv

Verwandte Themen