0 Daumen
42 Aufrufe

int* ptr = nullptr;
int val1 = 123, val2 = 234;
ptr = &val1;
int& ref1 = *ptr;
int& ref2 = val2;

cout << ref1 << endl;
cout << ref2 << endl;


//Zweiter teil des codes

*ptr = 456;
ptr = &val2;
*ptr = 678;

cout << ref1 << endl;
cout << ref2 << endl;

Aufgabe: was gibt dieser Code aus?

Meine Lösung: 

123
234
678 (falsch)
678

Des Buches Lösung:

123
234
456 (richtig)
678



Frage unten im vierten Schritt:

Die ersten zwei couts sind klar, 
Aber im zweiten Teil des Codes passiert meiner Meinung nach folgendes:


*ptr = 456;


Hier wird der Ursprüngliche Wert von val1 mit 456 überschrieben


ptr = &val2;


Der Pointer ptr, der vor dieser Zeile noch auf die Adresse von val1 gezeigt hat, zeigt nach diesem Code auf val2. 

*ptr = 678;


Der Pointer ptr zeigt ja jetzt auf die Adresse von val2. In diese Adresse wird jetzt der int-Wert 678 geschoben und der alte int-Wert 234 somit verworfen. 

cout << ref1 << endl;


Meine eigentliche Frage und Unklarheit:
ref1 soll nun outgeputtet werden, doch was ist ref1 überhaupt?
Ich schaue oben im ersten Teil wie ref 1 definiert ist und sehe, dass ref1 ein alias für den dereferenzierten Pointer ptr ist, also den int-Wert von der Adresse worauf ptr gerade zeigt herausgibt. 
Aber achtung, der ptr zeigt ja neuerdings die Adresse von val2, und val2 hat den Wert 678. Deswegen müsste hier doch 678 ausgegeben werden. (Das Buch zeigt 456 als Lösung an).


cout << ref2 << endl;


Was passiert hier ?
Hier soll ref2 outgeputtet werden. Was aber ist ref2 ? Ich schaue oben im ersten Teil des Codes nach.
ref2 ist ein Alias fpr val2 und val2 ist neu 678, also wird hier 678 ausgeputtet


Auch habe ich ein Bild dazu gezeichnet. 

pointer.png

von

1 Antwort

0 Daumen
doch was ist ref1 überhaupt?

ref1 ist eine Referenz auf den Speicherbereich, in dem val1 abgelegt wurde. Und zwar wegen

ptr = &val1;
int& ref1 = *ptr;

Aber achtung, der ptr zeigt ja neuerdings die Adresse von val2

Das weiß ref1 aber nicht. Eine Referenz zeigt immer auf den gleichen Speicherbereich. Eine Referenz ist halt kein Zeiger, der zu unterschiedlichen Zeitpunkten auf unterschiedliche Speicherbereiche zeigen kann. Deshalb funktioniert zum Beispiel folgendes nicht:

int& foo() {
int val = 5;
int& retval = &val;
return retval;
}
val ist eine lokale Variable. Das heißt ihr Speicherbereich wird freigegeben wenn foo() beendet wird. Der Wert 5 kommt also möglicherweise beim Aufrufer überhaupt nicht an. Dagegen funktioniert aber folgendes:

int& foo() {
    int* ptr = new int;
*ptr = 5;
    int& retval = *val;
    return retval;
}
Das ist zwar gruseliger Stil, aber legal.

von  –  ❤ Bedanken per Paypal

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage sofort und kostenfrei

x
Made by a lovely community
...