Given a memory address, is it possible to create an object from it?

444 Views Asked by At

In C#, if I create a hash table and get the memory address it's stored in, can I use that memory address in a different part of the program to recreate the hash table?

For example, can i do something like:

HashTable hash = new HashTable(oldHashPointer);
3

There are 3 best solutions below

7
Patrick Bell On

Yes and no. This isn't possible in C# in the way that you're describing it. For example the following code:

HashTable a = new HashTable();
HashTable b = a;

is essentially what you are trying to do, without explicit pointer usage. HashTable b isn't a seperate entity, it's a pointer to the reference stored in HashTable a, which points to a HashTable object in memory.

This MSDN article elaborates on this. A quote from the page:

Pointer types do not inherit from object and no conversions exist between pointer types and object. Also, boxing and unboxing do not support pointers.

However, if you're trying to share objects between processes (in this case, a HashTable), you could look into Memory Mapped Files. These will essentially allow you to write a serialized object into a virtual "file" residing in memory, that is also accessible from the other process. However, this is only available in .NET 4.0 or newer.

0
Jeroen van Langen On

C# is reference based, meaning you can create multiple variables pointing to the same instance.

ext10 already gave a nice example for it. So adding something in hasttable a, then it's also available for b. Because they are the same instance.

2
Artavazd Balayan On

It's possible. How to do it:

  1. Your class have to be marked with [StructLayout(LayoutKind.Sequential)] or (LayoutKind.Explicit)
  2. You should allocate in unmanaged memory needed amount of bytes var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T)));
  3. Copy your object to that pointer Marshal.StructureToPtr(obj, ptr, false);
  4. Create newObj and copy data to that object Marshal.PtrToStructure(ptr, newObj);
  5. Don't forget to free unmanaged memory or you'll get memory leaks Marshal.FreeHGlobal(ptr);

Update:

Code:

namespace MarhsalExampe
{
    using System;
    using System.Runtime.InteropServices;
    public class Program
    {
        [StructLayout(LayoutKind.Sequential)]
        public class SomeClass
        {
            public int IntProp { get; private set; }
            public string StrProp { get; private set; }
            public double DoubleProp { get; private set; }
            public bool BoolProp { get; private set; }

            public SomeClass() { }
            public SomeClass(int i, string s, double d, bool b)
            {
                IntProp = i;
                StrProp = s;
                DoubleProp = d;
                BoolProp = b;
            }
            public override string ToString()
            {
                return string.Format("HashCode: {0}, IntProp: {1}, StrProp: {2}, DoubleProp: {3}, BoolProp: {4}",
                    GetHashCode(), IntProp, StrProp, DoubleProp, BoolProp);
            }
        }
        public static void Main()
        {
            var obj = new SomeClass(42, "42", 42.0, true);
            Console.WriteLine("Obj is: {0}", obj);

            IntPtr ptr = IntPtr.Zero;
            try
            {
                // Allocate memory in unmanaged memory
                ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SomeClass)));
                // Copy data to ptr
                Marshal.StructureToPtr(obj, ptr, false);
                Console.WriteLine("Pointer: 0x{0:X}", ptr.ToInt64());

                // Create new object
                var newObj = new SomeClass();
                Console.WriteLine("newObj before updating from pointer: {0}", newObj);
                // Copy data to new object
                Marshal.PtrToStructure(ptr, newObj);

                Console.WriteLine("newObj after updating: {0}", newObj);
            }
            finally
            {
                if (ptr != IntPtr.Zero)
                    Marshal.FreeHGlobal(ptr);
            }
        }

    }
}