1

i need to create a variable length array of unmanaged object, but i need the array to be unmanaged too, so i can't use List<> or other classes but i have to malloc/realloc it in the c way.

this is my code:

unsafe class A{
    unsafe private int a1, a2;
    unsafe public byte* arr;
}

and on a different class method i would like to do something like this:

private unsafe A* arr = Marshal.AllocHGlobal(array_size * Marshal.SizeOf<A>());

Now i these questions:

  1. How to convert IntPtr to A*? OR does exist a proper c# malloc/realloc function? OR if i .dll import the real c/c++ realloc function would be safe to use it?
  2. How do i get a A* pointer to an A unmanaged object? if i try with '&' it says "cannot take the adress of [...] a managed object" but it shouldn't be managed. Am I doing something wrong in class declaration?

optional: why sizeof(A) doesn't work but Marshal.SizeOf() it's fine?

6
  • various performance reason but just on a small piece of code of critical value, mostly to use memcpy imported .dll. I started my project in c# believing that unsafe c# was the same as pure c, now i know i'm wrong but i don't want to rewrite my entire program. Commented Dec 1, 2017 at 13:13
  • Your A is not unmanaged, it's just regular .NET class (marking it with "unsafe" keyword doesn't change anything, and is redundant). Commented Dec 1, 2017 at 13:17
  • @evk so how i do creeate a unmanaged A object? Commented Dec 1, 2017 at 13:27
  • @Slai for the same exact code i posted i receive compiling error in VS 2017, did you changed something? Commented Dec 1, 2017 at 13:33
  • @DamianoDiVincenzo you can't. nothing short of writing some c/c++ code and than marshaling it to .net world. Commented Dec 1, 2017 at 13:33

1 Answer 1

2

You cannot use C# class for such things, but you can use struct:

[StructLayout(LayoutKind.Sequential)]
struct A
{
    public int A1;
    public int A2;
}

int array_size = 5;
// just cast IntPtr to A*
A* arr = (A*) Marshal.AllocHGlobal(array_size * Marshal.SizeOf<A>());
// set first element of unmanaged array
arr[0] = new A {A1 = 1, A2 = 2};
// set second
arr[1] = new A {A1 = 3, A2 = 4};

// alternative syntax:
// set first element
*arr = new A { A1 = 5, A2 = 6 };
// set second element
*(arr + 1) = new A { A1 = 5, A2 = 6 };
// get first element
var first = *arr;
var second = *(arr + 1);
Console.WriteLine(first.A1 + " " + first.A2);
Marshal.FreeHGlobal((IntPtr)arr);
Sign up to request clarification or add additional context in comments.

3 Comments

this works but it's on the stack, isn't it possible to do that on the heap?
@DamianoDiVincenzo it's not on the stack - it's in unmanaged memory you allocated with `AllocHGlobal'. Or you mean something different?
i think you are right. sorry, i got confused by the "struct" that usually are on the stack, but in this case i suppose it should be allocated inside the pointer area.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.