Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

cFx

Frischling

  • »cFx« ist der Autor dieses Themas
  • Private Nachricht senden

1

26.11.2015, 17:12

Pointer Speicher-Adressen

Hey zusammen,

bin jetzt am Ende des Kapitels über Pointer angelangt und beschäftige mich zZ damit, um die Dinger richtig zu verstehen. Soweit ist alles klar, jedoch habe ich ein kleines Verständnisproblem, was ich gerne aus der Welt schaffen möchte. Ich hoffe ihr könnt mir dabei helfen.

Hier mein Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<iostream>

using namespace std;

// Prototypes


int main()
{
    // Deklaration und Definition der Variable
    int nLevel = 1;

    // Entleerung des Pointers um Fehler vorzubeugen
    int *pLevel = NULL;

    // Pointer die Speicher-Adresse von nLevel zuweisen
    pLevel = &nLevel;

    // Speicher-Adresse der Variable nLevel ist im Pointer gespeichert
    // Wert von nLevel wird in Konsole ausgegeben
    cout << *pLevel << " *pLevel " << endl;
    // Speicher-Adresse von pLevel
    cout << &pLevel << " &pLevel " << endl;
    // Speicher-Adresse von nLevel
    cout << &nLevel << " &nLevel " << endl;
}


So wie ich das verstanden habe, ist der Pointer ein Verweis auf eine vorher deklarierte Variable. Dabei hat die Variable einen zugewiesenen Speicher im Stack (&nLevel). Nun kann ich aber sowohl die Adresse von der deklarierten Variablen (&nLevel) als auch von dem Pointer(&pLevel) aufrufen. Die Speicheradressen sind nicht wie ich angenommen hatte, die selben.

Rein vom Logischen her würde ich behaupten, dass &nLevel die Speicheradresse der Variablen ist, auf die wir mittels Pointer zugreifen. &pLevel hingegen die Speicheradresse ist, wo der Pointer gespeichert ist.
So könnte ich theoretisch Pointer auf Pointer verweisen lassen, wenn die dahinter verborgenen Variablen zu verschachtelt sind, um sie direkt über einen Pointer aufzurufen.

Mich würde jetzt interessieren ob ich mit meiner Annahme richtig liege, oder ob die beiden Speicheradressen auf den gleichen Speicherplatz verweisen oder sogar noch was ganz anderes =)

Würde mich über eine Aufklärung zu den unterschiedlichen Adressen freuen.

edit: Was mir noch grade aufgefallen ist, ist die Unklarheit zwischen dem Stack und dem Heap. So wie ich das verstehe, wird die Variable im Stack deklariert und definiert, also lokal. Sobald ich die Variablen-Adresse dann im Pointer speichere, bleibt der Speicher lokal. Das Einzige, was dann im Heap gespeichert wird, ist sozusagen die Pointer-Adresse, oder wird die lokale Variable, sobald ich sie einem Pointer zuweise komplett in den Heap verschoben?

mfg

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »cFx« (26.11.2015, 17:40) aus folgendem Grund: Rechtschreibung


2

26.11.2015, 18:23

C-/C++-Quelltext

1
int *pLevel = NULL;


Seit c++11 gibt es den nullptr.
Versuch den zu verwenden statt NULL.

cFx

Frischling

  • »cFx« ist der Autor dieses Themas
  • Private Nachricht senden

3

27.11.2015, 00:30

Danke euch beiden.

Das Video hab ich mir angeschaut, weiß aber immernoch nicht genau, was es mit dem Heap jetzt auf sich hat ... werde ich mich mal heute/morgen drüber informieren. Hab den Ersteller aber direkt mal abonniert, seine Erklärungen haben mir gefallen und ich denke, da werd ich des öfteren darauf zugreifen um mal alternative Erklärungen zu den Themen zu hören =)

Also anstatt:

int *pLevel = NULL;

int *pLevel = nullptr;

Vielen Dank für den Hinweis.

Dann bin ich ja zumindest mit den Zeigern nicht auf dem Holzweg, das ist ja schonmal gut zu wissen ^^

mfg

Tobiking

1x Rätselkönig

  • Private Nachricht senden

4

27.11.2015, 09:53

Heap wächst nur wenn du im Programm eine Variable darauf deklarierst. Stack wächst an wenn du innerhalb einer Funktion eine Variable einfach deklarierst.

Der Heap wächst nicht und man deklariert keine Variablen darauf. Der Heap ist ein Speicherbereich in dem man Stücke variabler Länge reservieren kann. Man spricht auch von Speicher anfordern und dynamischem Speicher. Das geschieht mit malloc, new etc. Man bekommt die Startadresse dieses Stücks und kann damit beliebige Daten dort ablegen. Man merkt sich daher natürlich diese Startadresse. Am Ende wird die Startadresse auch wieder gebraucht um die Reservierung aufzuheben. Damit ist auch der Unterschied zum Stack deutlich.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

27.11.2015, 10:10

Naja, wenn wir's hier wirklich genau nehmen wollen, müssten wir erstmal darauf hinweisen, dass es in C++ weder Heap noch Stack gibt, sondern nur automatische und dynamische Storage Duration... ;)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

27.11.2015, 10:22

Jetzt würde mich doch interessieren, wie genau dieser magische Heap das schafft, dass seine Größe konstant bleibt!?

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

7

27.11.2015, 10:26


Der Heap wächst nicht und man deklariert keine Variablen darauf.


Der Heap bleibt dann eben konstant in seiner Größe und man darf keine Variablen darauf deklarieren?! Hört sich gut an! :thumbup:

Auf dem Heap direkt deklariert man keine Variablen, nein. Man fragt beim OS Speicher an (ob man den auch bekommt, ist eine andere Frage), den man dann nutzen kann. Mehr nicht.
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

8

27.11.2015, 11:17

Den Grossteil der Informationen hier wirst du nie brauchen. Sie sind nur aus historischen Gruenden interessant und du wirst wahrscheinlich nie auf einen System arbeiten, wo dies nicht hinter einer Virtualisierung versteckt ist.

Was wirklich interessant ist:
  • Du legst zwei Vaiablen an, beide auf dem Stack "nLevel" und "pLevel"
  • nLevel belegt im Speicher 4 Byte auf den meisten aktuellen Compilern
  • pLevel belegt im Speicher 4 oder 8 Byte, je nachdem ob 32Bit oder 64bit exe
  • jedem dieser insgesagt 8/12 Bytes ist jeweils eine (virtuelle) Speicheradresse zugeordnet
  • so eine Speicheradresse ist einfach nur eine fortlaufende Integerzahl
  • die Speicheradresse des jeweils ersten Bytes nennt man auch "Adresse der Variable" (oder des Objekts)
  • in den 4 Byte von nLevel ist die binaere Repraesentation von 1 gespeichert
  • in den 4/8 Byte von pLevel ist die binaere Repraesentation der Adresse von nlevel gespeichert
  • &variable weisst den Compiler an die Adresse der Variable auzugeben
  • *variable weisst den Compiler, die Zahl in variable als Speicheradresse zu interpretieren und dort zu lesen/ schreiben

Und damit kannst du im Prinzip jede der Fragen aus dem Eingangspost selbst beantworten. Wie genau Stack oder Heap intern arbeiten muss man nicht wissen, man kann ihn auch einfach nur benutzen.

cFx

Frischling

  • »cFx« ist der Autor dieses Themas
  • Private Nachricht senden

9

27.11.2015, 11:21

Erstmal vielen Dank für die ganzen Antworten. Ich denke das reicht mir erstmal um eine räumliche Darstellung von dem Ganzen zu haben. Zu sehr ins Detail wollte ich erstmal nicht gehen.

@[Anonymer Benutzer] So wie ich das verstanden habe, sollte ich nicht auf Variablen in anderen Funktionen zeigen, da dieser Stackframe sich ggf. früher löscht. Der Pointer würde daraufhin ein Eigenleben entwickeln und im schlimmsten Fall auf eine komplett andere Variable zeigen, die rein zufällig die gleiche Speicheradresse hat, wie die angegebene Variable.

edit:

@TGGC Vielen Dank für die kompakte Fassung =)Ja, Fragen sind jetzt alle beantwortet =D

mfg

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »cFx« (27.11.2015, 11:29)


TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

10

27.11.2015, 11:39

@[Anonymer Benutzer] So wie ich das verstanden habe, sollte ich nicht auf Variablen in anderen Funktionen zeigen
Doch, das sollte man unbedingt machen! Das passiert naemlich nicht zufaellig, sondern genau definiert und hat auch nicht nur mit Funktionen zu tun. Fuer jede Variable ist genau definiert, wie lange sie gueltig ist und damit auch wie lange ein Pointer darauf verwendet werden darf. In kurz gilt fuer lokale Variablen, sie sind nutzbar, bis sie out of scope gehen und fuer Variablen auf dem Heap bis man sie mit delete loescht.

Verliere dich bitte nicht in Details, in denen sind hier jetzt auch schon einige Fehler und Fallstricke versteckt. Als Anfaenger ist das aber alles unnoetiger Ballast, da du darauf nie direkt zugreifen solltest. Du machst den Stack z.B. nie aktiv groesser durch einen speziellen Befehl. Daher kann dir erstmal egal sein, ob er waechst oder nicht. Mit hoher Wahrscheinlichkeit wird dein Stack auch nicht wachsen und wenn du irgendwann mal indirekt zu viel Speicher darauf verbrauchst, wirst du Fehlermeldungen erhalten. Dann ist aber immer noch Zeit sich damit zu beschaeftigen.

Werbeanzeige