Autor Beitrag
stolpervogel
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Fr 11.10.13 13:37 
Hallo,

ich habe eigentlich eine recht simple Frage so gesehen, finde aber keine Lösung beim Googlen.
Ich beschäftige mich etwas mit dem Garbage Collector und will testen, wie lange zb. eine Variable im Stack erhalten bleibt bis dieser wieder verworfen wird.

dazu wüsste ich gern die Speicher Adresse einer Variable.

Jetzt komme ich aus dem C Bereich und hab schnell gemerkt, dass es bei C# erstmal nicht möglich ist mit Pointer/Zeiger zu arbeiten außer im Unsafe Mod.
Ich habe jetzt folgenden Code:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
public static unsafe void Main()
{
    int variable = int.Parse(Console.ReadLine());
    int* ptr1 = &variable;

    Console.WriteLine(*ptr1);
            
    Console.WriteLine( ptr1);
}

Wie kann ich jetzt die Adresse auf die der Pointer *ptr zeigt ausgeben lassen?
ausblenden C#-Quelltext
1:
Console.WriteLine(*ptr1);					

liefert mir den Wert der variable.
ausblenden C#-Quelltext
1:
Console.WriteLine(ptr1);					

ist nicht möglich mit der Meldung: Argument 1: cannot convert from 'int*' to 'string'
Gibt es da eine Lösung int* zum String zu convertieren?

Oder wie kann man das sonst noch anders lösen?

Würde es eher gehen wenn ich eine string variable nutzen würde, bzw. gibt es pointer die auf string Variablen verweisen?

Vielen Dank schonmal für eure Antworten

Moderiert von user profile iconTh69: Quote- durch C#-Tags ersetzt
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 11.10.13 14:32 
Das wa du da bekommst ist kein Pointer sondern eine Referenz und eine Referenz zeigt nicht dauerhaft auf die richtige Speicheradresse. Der Garbage Collector kann die verschieben. Insofern müßtest du die Referenz erst pinnen (das fixed Schlüsselwort) damit es nicht mehr verschoben werden kann und du damit irgendwas sinnvolles machen könntest. Da du aber den Garbage Collector auf die Finger schauen willst ist das irgendwie sinnfrei. Mit fixed hast du im Prinzip das GC Verhalten abgeschaltet damit man selbst einen halbwegs gefahrlosen Blick in den Speicher werfen kann.

Und nebenbei eine Referenz/Pointer ist nicht zwingend Int. Benutz wenn schon IntPtr das kapselt den 4Byte/8Byte Unterschied je nach Bittigkeit.

Wenn du schnell mal die Adresse eine Objects ausgeben will dann hol die einen GCHandle ran.

ausblenden C#-Quelltext
1:
2:
IntPtr adress = GCHandle.Alloc(MeinLiebesObject, GCHandleType.Pinned).AddrOfPinnedObject();
Console.WriteLine(adress);


Moderiert von user profile iconTh69: Quote- durch C#-Tags ersetzt
stolpervogel Threadstarter
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Mo 14.10.13 08:45 
Hallo Ralf, danke für deine Antwort.

inzwischen hab ich selbst schon eine Lösung... dachte ich bis ich dein code hier gesehen und getestet habe.
ich hatte folgendes gemacht und zwar:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
    String zeichen = Console.ReadLine();
            
    IntPtr ptr = Marshal.StringToCoTaskMemAnsi(zeichen);
    string adresse = ptr.ToString("X4");
    Console.WriteLine("0x00" + adresse);


Marshal liefert mir auch eine Hex adresse, dachte ich jedenfalls bis ich dein Vorschlag ausprobiert hatte.
Jedoch sind die beiden Hex adressen unterschiedlich... nun frag ich mich welche von beiden stimmt..?!

ausblenden C#-Quelltext
1:
2:
    IntPtr adress1 = GCHandle.Alloc(zeichen, GCHandleType.Pinned).AddrOfPinnedObject();
    Console.WriteLine("0x00" + adress1.ToString("X"));


oder was genau liefert mir Marshal.StringToCoTaskMemAnsi(zeichen)?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 14.10.13 10:54 
Das was du an der Marshal Klasse findest dient immer dem Interop mit unmananged Code. Ich habe keine spezielle Erfahrung mit StringToCoTaskMemAnsi aber die Doku ist doch eindeutig. Du bekommst eine ~Kopie~ des Strings im nicht gemanagten Speicherbereich zum COM Interop.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4796
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 14.10.13 13:15 
Hallo stolpervogel,

bitte Crossposts (s. Richtlinien) immer angeben: myCSharp.de - Auslesen von Speicheradressen in C#.

Für diesen Beitrag haben gedankt: stolpervogel