stackalloc
suggest changeThe stackalloc
keyword creates a region of memory on the stack and returns a pointer to the start of that memory. Stack allocated memory is automatically removed when the scope it was created in is exited.
//Allocate 1024 bytes. This returns a pointer to the first byte.
byte* ptr = stackalloc byte[1024];
//Assign some values...
ptr[0] = 109;
ptr[1] = 13;
ptr[2] = 232;
...
Used in an unsafe context.
As with all pointers in C# there is no bounds checking on reads and assignments. Reading beyond the bounds of the allocated memory will have unpredictable results - it may access some arbitrary location within memory or it may cause an access violation exception.
//Allocate 1 byte
byte* ptr = stackalloc byte[1];
//Unpredictable results...
ptr[10] = 1;
ptr[-1] = 2;
Stack allocated memory is automatically removed when the scope it was created in is exited. This means that you should never return the memory created with stackalloc or store it beyond the lifetime of the scope.
unsafe IntPtr Leak() {
// allocate some memory on the stack
var ptr = stackalloc byte[1024];
// return a pointer to that memory (this exits the scope of "Leak")
return new IntPtr(ptr);
}
unsafe void Bad() {
// ptr is now an invalid pointer, using it in any way will have
// unpredictable results. This is exactly the same as accessing beyond
// the bounds of the pointer.
var ptr = Leak();
}
stackalloc
can only be used when declaring and initialising variables. The following is not valid:
byte* ptr;
...
ptr = stackalloc byte[1024];
Remarks:
stackalloc
should only be used for performance optimizations (either for computation or interop). This is due to the fact that:
- The garbage collector is not required as the memory is allocated on the stack rather than the heap - the memory is released as soon as the variable goes out of scope
- It is faster to allocate memory on the stack rather than the heap
- Increase the chance of cache hits on the CPU due to the locality of data