-1

I'm trying to have a stack allocated array inside a struct. Well the pointer I mean. But I'd like the allocation to be done without extra code because I know the size when I write the code (I don't want to do a bunch of new when I create my struct). If I can even do it without unsafe context that's perfect. I tried some stuff, but it's not doing fine. I'm brand new to C# so there is probably a way to do it that I didn't see !

public struct TestValue {int value; }

[StructLayout(LayoutKind.Sequential)]
public struct TestArray {
   [MarshalAs(UnmanagedType.ByValArray, SizeConst=128)] public TestValue[] s1;
}

public struct TestSpan
{
    Span<TestValue> data= stackalloc TestValue[10];
}
mrbm
  • 1,136
  • 1
  • 12
  • 36
Mathieu Van Nevel
  • 1,428
  • 1
  • 10
  • 26
  • 1
    [MarshalAs] plays no role here, only the pinvoke marshaler pays attention to it. You need to use a [fixed size buffer](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/unsafe-code-pointers/fixed-size-buffers) to get the array stored on the stack. Be careful to not index it out of bounds. And be careful, when you're new to C# then it is far too easy to prematurely optimize code. You only get a feel for how efficient the GC is when you try it. – Hans Passant Dec 15 '18 at 11:06
  • @HansPassant that's not optimization, just common sense here. But I can't use a fixed buffer because it's only for primitive types :/ – Mathieu Van Nevel Dec 15 '18 at 11:11
  • 2
    Knowing C or C++ well is not exactly an asset, you'll get the wrong kind of common sense. C# has its own, it doesn't look like that. – Hans Passant Dec 15 '18 at 11:12
  • @HansPassant how is that wrong to use the stack for data that you don't need to refer outside? – Mathieu Van Nevel Dec 15 '18 at 11:14
  • It is dangerous and 99.9% of the time not necessary. The GC just doesn't suck. You can only find out if it is necessary when you profile, you haven't done that yet. – Hans Passant Dec 15 '18 at 11:16
  • @HansPassant dangerous? sorry I feel like 99.9% of the time it's heap allocation that isn't necessary. That the gc suck or not isn't the problem. There is no move semantice with C# so I'll probably use a bit more the heap though. Anyway that won't answer my question ^^ – Mathieu Van Nevel Dec 15 '18 at 11:19
  • 2
    If you know what move semantics means then you must be familiar with the problems caused by stack buffer overflow. Not just the UB, also how exploitable that is by malware. That kind of dangerous. But feel free to do it your way, I don't need to convince you today. – Hans Passant Dec 15 '18 at 11:24

1 Answers1

1
using System.Runtime.InteropServices;

public struct TestValue {int value; }

[StructLayout(LayoutKind.Sequential)]
public struct TestArray {
   [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=128)] public TestValue[] s1;
}

public class Foo
{
    void test()
    {
        TestArray test = new TestArray();
        test.s1[10] = new TestValue();
    }
}

I needed just a small change in the end!

Mathieu Van Nevel
  • 1,428
  • 1
  • 10
  • 26