Ah okay. Danke.
Aber kannst du mir das mit dem Stackframe vielleicht noch etwas genauer erklären?
Es wundert mich schon, dass der Pointer auf die Adresse von v zeigt, obwohl ich ja der ptrfunc bo übergebe und das v doch eine Kopie von bo in einem anderen Adressbereich erstellen sollte.
Demnach sollte das doch trotzdem verschiedene Adressen anzeigen?!
So ganz ok scheint es demnach noch nicht zu sein
![Wink ;) ;)](https://cdn.jsdelivr.net/joypixels/assets/8.0/png/unicode/64/1f609.png)
. Also pass auf:
Ein Programm besitzt ja für gewöhnlich EINEN Stack der ab einer bestimmten Adresse anfängt. Dieser Stack wird bei Funktionsaufrufen auf - und abgebaut.
Nun wie sieht so ein Stackaufbau im Allgemeinen nach einem Funktionsaufruf (also wenn wir uns in der aufgerufenen Funktion befinden) aus?:
Code:
|---------------------------|
| funktionslokale Parameter | (je nachdem wieviele lokale Parameter in der Funktion deklariert sind)
|---------------------------|
| Framepointer (FP) | (4 bytes)
|---------------------------|
| Programcounter (PC) | (4 bytes)
|---------------------------|
| aktuelle Parameter | (je nachdem was für welche und wieviele Paras übergeben werden)
|---------------------------|
Die Begriffe kurz erläutert:
Die aktuellen Parameter: sind die Parameter, die der Funktion übergeben werden. Sie werden bei einem Funktionsaufruf zuerst auf den Stack kopiert damit die Funktion auch darauf zugreifen kann.
Die Restaurierung des Programcounter (der Zeiger der in deiner CPU immer auf den aktuellen Befehl zeigt)(PC) dient dazu damit, wenn die Funktion via return zurückkehrt, der Prozessor weiß wo er mal aufgehört hat um dort dann weiter zu machen.
Der Framepointer wird dazu benutzt um auf Funktionslokale- und aktuelle Parameter zugreifen zu können.
Die Funktionslokalen Parameter sind die Variablen die innerhalb der Funktion deklariert wurden.
Ich hab dir das mal versucht ASCII Art mäßig darzustellen:
Stackaufbau wenn die Abarbeitung des Programmes Zeile 22 erreicht hat:
Code:
| | höhere Adressen
|---------------------------------------------|
| in main deklarierte Variablen |
|---------------------------------------------|
| FP (main) |
|---------------------------------------------|
| PC (auf die Stelle wo main aufgerufen wird) |
|---------------------------------------------|
| argc |
|---------------------------------------------|
| argv | niedere Adressen
|---------------------------------------------|
jetzt nachdem dein Programm Zeile 33 erreicht hat (also sich in valfunc befindet):
Code:
| | höhere Adressen
| in valfunc deklarierte Variablen |
|----------------------------------------|
| FP (für Funktion valfunc) |
|----------------------------------------|
| PC (zeigt auf den Befehl in Zeile 15) |
|----------------------------------------|
| bigone v | <--- das ist die Adresse &v (*)
|----------------------------------------|
| in main deklarierte Variablen |
|----------------------------------------|
| FP (main) |
|----------------------------------------|
| PC (auf die Stelle vor main) |
|----------------------------------------|
| argc |
|----------------------------------------|
|argv | niedere Adressen
|----------------------------------------|
Nachdem valfunc erfolgreich beendet wurde (also mit return zurückgesprungen ist) und der Stack wieder abgebaut wurde sieht der Stack wieder so aus:
Code:
| | höhere Adressen
|---------------------------------------------|
| in main deklarierte Variablen |
|---------------------------------------------|
| FP (main) |
|---------------------------------------------|
| PC (auf die Stelle wo main aufgerufen wird) |
|---------------------------------------------|
| argc |
|---------------------------------------------|
| argv | niedere Adressen
|---------------------------------------------|
dein Programm hat Zeile 40 erreicht (befindet sich also in ptrfunc):
Code:
| | höhere Adressen
| in ptrfunc deklarierte Variablen |
|----------------------------------------|
| FP (für Funktion ptrfunc) |
|----------------------------------------|
| PC (zeigt auf den Befehl in Zeile 15) |
|----------------------------------------|
| bigone *p | <---- das ist die Adresse &p (**)
|----------------------------------------|
| in main deklarierte Variablen |
|----------------------------------------|
| FP (main) |
|----------------------------------------|
| PC (auf die Stelle vor main) |
|----------------------------------------|
| argc |
|----------------------------------------|
|argv | niedere Adressen
|----------------------------------------|
Wie man sieht sind (*) und (**) beides mal dieselben Adressen, obwohl es 2 unterschiedliche Objekte sind! v ist nämlich definitiv eine Kopie auf dem Stack von deinem gglobalen bo, und p definitiv ein Pointer auf dein globales bo. Wenn du die Unterschiede zeigen willst musst du anstatt:
C++:
//in valfunc
cout << &v << endl;
//in ptrfunc
cout << &p << endl;
C++:
//in valfunc
cout << &v << endl;
//in ptrfunc
cout << p << endl;
schreiben.
So du wolltest es wissen
![Smile :) :)](https://cdn.jsdelivr.net/joypixels/assets/8.0/png/unicode/64/1f642.png)
.
Siehe dazu auch
http://www.tutorials.de/forum/linux-unix/252183-suse-9-0-speicherreservierung-fuer-char-stack.html
HTH,
RedWing