Frage

I was playing with stackalloc and it throwsoverflow exception when I wrote below piece of code:-

var test = 0x40000000;
        unsafe
        {              
            int* result = stackalloc int[test];
            result[0] = 5;
         }

and when I make changes in test variable as shown below it throws stack overflow exception.

 var test = 0x30000000;
            unsafe
            {              
                int* result = stackalloc int[test];
                result[0] = 5;
             }

what is happening in both scenario??

War es hilfreich?

Lösung

The runtime tries to calculate how much space is needed to store your array, and the first array is too large for the result to fit in the range of the type used.

The first array needs 0x40000000 * 4 = 0x0100000000 bytes of storage, while the second one needs only 0xc0000000 bytes.

Tweaking the array size and the array type (e.g. long[] or char[]) indicates that whenever the required space for the array goes over 0xffffffff you get the OverflowException; otherwise, the runtime attempts to create the array and crashes.

Based on the above I think it's fairly safe to conclude that the required space is being calculated using a value of type uint in a checked context. If the calculation overflows you unsurprisingly get the OverflowException; otherwise the runtime blows up due to the invalid unsafe operation.

Andere Tipps

Both arrays are larger than the largest allowed size of a single object in .NET (which is 2GB regardless of the platform), meaning that this would fail even if you didn't try to allocate in on the stack.

In the first case, you need 4 * 0x40000000 bytes (int is 32-bit in .NET), which doesn't even fit inside 32-bits and creates an arithmetic overflow. The second case needs ~3GB but is still way larger than the 2GB limit.

Additionally, since you're trying to allocate on the stack, you need to know that the stack size for a single thread is ~1MB by default, so using stackalloc for anything larger than that will also fail.

For example, this will also throw a StackOverflowException:

unsafe
{
    byte* result = stackalloc byte[1024 * 1024];
    result[0] = 5;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top