Grundsätzliches zu Adressbereichen - Verständnisfrage

player1

Mitglied
Hallo

Also ich beschäftige mich gerade mit C++. Habe vorher viel mit Java gearbeitet und wollte jetzt mit C++ langsam weitermachen.

Also ich habe dieses Programm:

Code:
int main()
{
    string bier = "Weizen";   
    cout << &bier << ": " << bier << endl;
    cin.get();
}
Die Ausgabe ist klar sieht dann zB so aus:

0x22ff50: Weizen

Nun habe ich aus Interesse einen Hex-Editor installiert, der mir den kompletten Inhalt des Arbeitsspeichers anzeigen kann.
In der ewig langen Liste findet man links also immer den "Offset" ( Offset == Speicheradresse ? ) und in den Zellen in der Mitte den Inhalt in Hex-Form in 2er- Blöcken (8bit).Ganz rechts ist dann eine Zelle, die wohl die dementsprechenden ASCII-Zeichen ausgibt.

Meine naive Annahme war nun, das ich meinen String bier mit dem Inhalt "Weizen" nun bei Offset 0x22ff50 (Programm läuft noch) finden würde. Das war leider nicht der Fall.

Also meine Frage ist eigentlich: Was hat es mit der Adresse 0x22ff50 auf sich und wie ist der Zusammenhang zum Arbeitsspeicher?
 
Zuletzt bearbeitet:
Bei manchen computer-Architekturen (z.B. Intel) werden Bit-Worte (bytes, manchmal aber auch eine andere Anzahl bits) von "rechts nach links" geschrieben.
Die verschiedenen Bit-Worte werden dann aber von "links nach rechts" aneinandergereiht.
Man nennt das dann Little-Endian Reihenfolge.
(Ich bin mir nicht sicher, ob ich's richtig erklärt habe)

http://de.wikipedia.org/wiki/Little_endian

Ich weiss nicht, ob dass das Problem löst. Mit Speicher-Architekturen bin ich nicht vertraut. Desshalb wäre ich auch an einer Antwort interessiert.

Übrigens haben viele Debugger einen Speicher-Betrachter eingebaut. Da brauchst du nicht einen separaten Hex-Editor.

Gruss Lukes
 
Zuletzt bearbeitet:
Hi.

Jedes Programm bekommt einen eigenen (virtuellen) Adressraum zugewiesen. Du müßtest also erstmal herausfinden wo der Speicher für das Programm beginnt und dann den Offset von 0x22ff50 hinzufügen - so solltest du zu der Lokation der Variablen bier kommen.

Doch dort steht nicht die Byte-Folge "Weizen" da dort nur die Daten der Klasse string zu finden sind. Die string Klasse verwaltet intern Speicher für den gespeicherten Text - der wiederum an einer ganz anderen Stelle zu finden ist.

Siehe http://de.wikipedia.org/wiki/Virtuelle_Speicherverwaltung.

Gruß
 
Zuletzt bearbeitet:
Also ist es doch nicht so offensichtlich wie ich dachte. Ich werde mir den Artikel mal genau durchlesen, dass ist schon interessant..

Doch dort steht nicht die Byte-Folge "Weizen" da dort nur die Daten der Klasse string zu finden sind.

Die Daten der ganzen Klasse? Was heißt das genau? Also die Struktur der String-Klasse doch wohl nicht oder?
Hier ein Vergleich: Wenn ich in PHP ein Objekt einer Klasse erstelle, dann kann ich dieses Objekt praktisch als (mehrdimensionales) Array ausgeben. In diesem Array stehen dann gerade alle aktuellen Werte aller Variablen(Felder). Hat eine Variable dort wieder den Typ irgendeiner Klasse, dann geht das Array sozusagen ein Niveau tiefer und macht das selbe mit diesem Objekt.
Jedenfalls ist es da dann so, dass keine Informationen über die Aufbau einer Klasse gespeichert werden, nur die aktuellen Werte der Felder.
 
Also ist es doch nicht so offensichtlich wie ich dachte. Ich werde mir den Artikel mal genau durchlesen, dass ist schon interessant..



Die Daten der ganzen Klasse? Was heißt das genau? Also die Struktur der String-Klasse doch wohl nicht oder?
Hier ein Vergleich: Wenn ich in PHP ein Objekt einer Klasse erstelle, dann kann ich dieses Objekt praktisch als (mehrdimensionales) Array ausgeben. In diesem Array stehen dann gerade alle aktuellen Werte aller Variablen(Felder). Hat eine Variable dort wieder den Typ irgendeiner Klasse, dann geht das Array sozusagen ein Niveau tiefer und macht das selbe mit diesem Objekt.
Jedenfalls ist es da dann so, dass keine Informationen über die Aufbau einer Klasse gespeichert werden, nur die aktuellen Werte der Felder.


Das absolut einzige was PHP und C gemeinsam haben ist die ähnliche Syntax und das kommt nur daher, weil der PHP Entwickler eine Syntax wollte die allgemein bekannt ist. Ansonsten kannst Du PHP und C++ überhaupt gar nicht miteinander vergleichen, denn sie haben nichts gemeinsam. (Angafangen damit das das eine eine Interpretersprache ist, das ander eine Compilersprache.)
 
Ja ok. Der Vergleich sollte auch nur deutlich machen, was ich meine mit Klassenstruktur (Implementierung) und die aktuellen Werte der Variablen(Felder) in dem Objekt (hehe, das is jetzt wahrscheinlich noch viel deutlicher als mit Vergleich)

Also die Frage ist ja: Was ist an jener Adresse dann in diesem Fall zu finden?
 
Zuletzt bearbeitet:
Die Daten der ganzen Klasse? Was heißt das genau? Also die Struktur der String-Klasse doch wohl nicht oder? ...

Jedenfalls ist es da dann so, dass keine Informationen über die Aufbau einer Klasse gespeichert werden, nur die aktuellen Werte der Felder.

Das ist in C++ im Prinzip genauso. Beim Erzeugen der Instanz wird soviel Speicher auf dem Heap (bzw. Stack) allokiert, wie die Daten der Klasse brauchen. (Die Information über die Sruktur weiss ja der Compiler aus der Klassendefinition. )
Danach wird der Konstruktor ausgeführt, um den Speicher zu initialisieren.

Was deepthroat meint ist folgendes. Nicht die Klasseninformationen, sondern die Daten der Klasse string werden vorgehalten. Die Klasse string hat intern eine Membervariable, warscheinlich vom typ char *, welche auf den eigentlichen string verweist. Die Adresse, die Du in Deinen Codefragment siehts, ist also nicht die Adresse des charakterbuffers, sondern der Instanz von string.

Im alten C gab es keinen Typ string. Da musste man mit char * arbeiten. Die Möglichkeit zur Stringverarbeitung wurde über eine Bibliothek von Funktionen z.B. strcpy o.Ä zur verfügung gestellt. In einer OO Sprache wie C++, ist sowas Käse, weil man eine Einheit aus Eigenschaften (char *) und Methoden (strcpy) möchte. also zimmert man ein Klasse string, die den char * dünn umhüllt.


Konkret hier passiert folgendes. zunächst legst Du einen string an. Im Grunde machst Du dabei eigentlich folgendes. Du allokierst (in Deinem Fall auf dem Stack) soviel Speicher, wie ein char * (4 Byte oder so) braucht. Dann wird der Konstruktor von string aufgerufen, der den Speicher für "Weizen" allokiert. Diese Adresse merkt er sich im char *. Du hast also 2 "Instanzen", wenn Du so willst. Eine string Instanz und ein Array von char. Was &bier ausgibt ist logischerweise nicht die Adresse der internen Varivalen char*, sondern der Instanz der Klasse string (der Hülle).

Ich hoffe das war halbwegs klar...

Gruss
 
Das war sogar sehr gut erklärt, danke. Werd da jetzt mal ein bisschen rumspielen und mich wohl wieder melden :)

Gruß
player1
 

Neue Beiträge

Zurück