Speicherverwaltung

Schnelle objektorientierte, kompilierende Programmiersprache.
Uzaku
Beiträge: 55
Registriert: So Aug 09, 2009 1:47 pm

Speicherverwaltung

Beitrag von Uzaku » Sa Dez 26, 2009 9:00 pm

Hi, ich habe gewisse Situationen, bei Speicherzugriffen, und bin mir gerade nicht sicher, was erlaubt ist, und was nicht.

Code: Alles auswählen

class B{
    public:
        B(){}
        ~B(){}
        
        set(int* PX, int* PY){
            pX = PX;
            pY = PY;
        }
        
    private:
        int *pX;
        int *pY;
};

class A{
    public:
        A(){
            pX = &X;
            pY = new int;
        }
        ~A(){
             delete pY;
        }
        
        get_pX(){return pX;}
        get_pY(){return pY;}

    private:
        int X;
        int *pX;
        int *pY;
};

int main(){
    A a;
    B b;
    
    b.set(a.get_pX, a.get_pY)
    return 0;
}
Wie sieht das jetzt aus, könnte b jetzt Fehlerfrei auf die werte X und Y von a zugreifen, oder geht das nicht, weil sie private variablen sind, oder geht es bei Y, weil das per new erstellt wurde und bei X nicht?
was würde der exakt selbe code bewirken, wenn der einzige unterschied wäre, dass man der klasse A die Klasse B als friend hinzufügt ?

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Speicherverwaltung

Beitrag von nufan » Sa Dez 26, 2009 9:30 pm

Wie sieht das jetzt aus, könnte b jetzt Fehlerfrei auf die werte X und Y von a zugreifen, oder geht das nicht, weil sie private variablen sind
b (oder allgemein B) kann in diesem Fall nur über die beiden get-Methoden die Werte von a auslesen (aber nicht verändern).

Code: Alles auswählen

b.set(a.get_pX, a.get_pY)
Schwer zu sagen was da rauskommt, weil die get-Methoden keinen Rückgabetyp haben. Ich nehme mal int an.
Du übergibst hier übrigens zwei Funktionszeiger (schätze mal nicht beabsichtigt), was jedenfalls zu keinem sinnvollen Ergebnis führt. Du solltest die Rückgabewerte der Funktionen vorher auf zwei Hilfsvariablen speichern und deren Adressen übergeben. Diese Hilfsvariablen sind dann _Kopien_ der Variablen in A, wodurch du sie (überall) beliebig ändern kannst. Die Daten in A bleiben dabei aber unverändert. Anders siehts aus wenn du Referenzen (int&) zurückgibst. Dann haben die Änderungen nämlich auch Einfluss auf den Inhalt des Objekts von Typ A.
geht es bei Y, weil das per new erstellt wurde und bei X nicht?
Das macht überhaupt keinen Unterschied.
was würde der exakt selbe code bewirken, wenn der einzige unterschied wäre, dass man der klasse A die Klasse B als friend hinzufügt ?
Dann könntest du innerhalb von B auf private Member der Klasse A zugreifen. Du hast aber in B kein A. Wichtig ist zu unterscheiden, ob du mit Kopien der einzelnen Werte in A oder mit einer Instanz von A selbst arbeitest.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Speicherverwaltung

Beitrag von Xin » Sa Dez 26, 2009 11:12 pm

Das wird kompiliert??

Die beiden get-Funktionen werden nicht gerufen, es wird die Adresse der Funktion übergeben.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Uzaku
Beiträge: 55
Registriert: So Aug 09, 2009 1:47 pm

Re: Speicherverwaltung

Beitrag von Uzaku » Sa Dez 26, 2009 11:28 pm

Lol, der Code oben wird selbstverständlich nicht übersetzt. Ich habe auch nur versucht, mein Problem exemplarisch zusammenzuschrumpfen. Ich versuche es nochmal, und hoffe, dass diesesmal alle Fehler raus sind

Code: Alles auswählen

    class B{
        public:
            B(){}
            ~B(){}
           
            void set(int* PX, int* PY){
                pX = PX;
                pY = PY;
            }
           
        private:
            int *pX;
            int *pY;
    };

    class A{
        public:
            A(){
                pX = &X;
                pY = new int;
            }
            ~A(){
                 delete pY;
            }
           
            int *get_pX(){return pX;}
            int *get_pY(){return pY;}

        private:
            int X;
            int *pX;
            int *pY;
    };

    int main(){
        A a;
        B b;
       
        b.set(a.get_pX(), a.get_pY());
        return 0;
    }
Der Springende Punkt ist, ob jetzt innerhalb von B, über die Zeiger die von A kommen, die Variablen, die in A erzeugt wurden, gelesen und verändert werden können.

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Speicherverwaltung

Beitrag von nufan » So Dez 27, 2009 12:09 am

Cracker 1991 hat geschrieben:Der Springende Punkt ist, ob jetzt innerhalb von B, über die Zeiger die von A kommen, die Variablen, die in A erzeugt wurden, gelesen und verändert werden können.
Ja, kannst du. Genau das ist ja der Sinn von get- und set-Methoden. Was du aber nicht kannst:

Code: Alles auswählen

a.X = 0;

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Speicherverwaltung

Beitrag von Xin » So Dez 27, 2009 8:34 am

Cracker 1991 hat geschrieben:Der Springende Punkt ist, ob jetzt innerhalb von B, über die Zeiger die von A kommen, die Variablen, die in A erzeugt wurden, gelesen und verändert werden können.
Die Adresse ist auch nur eine Zahl und die wird bei einem * (Zeiger) nur kopiert.
Der Speicherbereich gehört Dir, also darfst Du dort lesen und schreiben.

Wenn Du nicht willst, dass jemand den Wert auslesen kann, dann darfst Du keine getter anbieten. Wenn Du das Auslesen erlauben möchtest, aber verbieten möchtest, dass jemand da was reinschreiben kann, dann gibst Du ein (int const *) zurück.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Uzaku
Beiträge: 55
Registriert: So Aug 09, 2009 1:47 pm

Re: Speicherverwaltung

Beitrag von Uzaku » So Dez 27, 2009 10:24 am

Das hatte ich gehofft. Allerdings hatte ich meine Zweifel, ich weiß, dass Zeiger eigentlich genau dafür gemacht sind, aber Zeiger sind ja aus C und ich hatte Angst, dass die Private-Member irgendwie extra geschützt sind.
Allerdings habe ich dann ein Anderes Problem. Ich versuche nämlich genau das, aber es geht nicht.
Ich habe ein Zeiger auf ein CURL struct der libcurl. Das struct wurde per curl_easy_init(); erzeugt. Jetzt ist in diesem Struct ja alles gespeichert, was CURL so braucht, und ich brauchte dann genau dieses Struct in einer anderen Klasse, und habe deshalb den Zeiger darauf übergeben. Dummerweise gehen dann merkwürdigerweise Infos flöten. Denn das curl_easy_perform() funktioniert nicht in Klasse B. Wenn ich es in Klasse A mache, dann funktioniert es. Es ist auch sichergestellt, dass an dem Struct nichts mehr geändert wird, zwischen der Zeit, wo ich es in A getestet habe, und der Zeit, wo es in B ausgeführt wird. Wenn ich das Ganze debugge, dann sagt der Debugger auch beim Zeiger in Klasse B: nicht auswertbar.

Uzaku
Beiträge: 55
Registriert: So Aug 09, 2009 1:47 pm

Re: Speicherverwaltung

Beitrag von Uzaku » So Dez 27, 2009 11:27 am

das mit dem nur eine Stunde Editierbar sollte man wirklich mal ändern.
Genau genommen sagt der Debugger: "Connection CXX0069: Fehler: Variable erfordert Stapelrahmen"

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Speicherverwaltung

Beitrag von Xin » So Dez 27, 2009 12:17 pm

Cracker 1991 hat geschrieben:das mit dem nur eine Stunde Editierbar sollte man wirklich mal ändern.
Nö, das ist ja extra eingerichtet. Das Forum ist nicht versioniert, ergo muss man irgendwann eine Version abschließen.

Du kannst Rechtschreibfehler korrigieren, aber wenn Du einen Gedanken hinzufügen möchtest oder Deine Meinung änderst, dann sehen alle anderen blöd aus, weil es so aussieht, als ob sie falsch antworten.
Cracker 1991 hat geschrieben:Genau genommen sagt der Debugger: "Connection CXX0069: Fehler: Variable erfordert Stapelrahmen"
Und welche Variable? ^^

CXX0069 klingt nach Visual Studio... da komme ich frühstens heute abend zu.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Uzaku
Beiträge: 55
Registriert: So Aug 09, 2009 1:47 pm

Re: Speicherverwaltung

Beitrag von Uzaku » So Dez 27, 2009 12:37 pm

Richtig, Visual Studio.
Die Variable Connection.
Die Fehlermeldung kommt dann dahinter.
Connection ist ein CURL* und ihm wurde ein CURL* aus dem Privaten Bereich einer anderen Klasse mittels einer set-Methode zugewiesen.

Antworten