Edit

Share via


Compiler Error CS8352

Cannot use variable 'variable' in this context because it may expose referenced variables outside of their declaration scope.

This error indicates potential undefined behavior when there's a risk of accessing a stack-allocated variable after it's already been deleted from the stack.

To correct this error

You fix CS8352 by ensuring the variable's scope is at least as wide as the variable that refers to it. You do this by allocating the storage on a heap, or in the stack on the calling context.

Example

The following sample generates CS8352:

C#
class Program
{
    static public Span<int> CreateSpanWithValue(int size, int value)
    {
        Span<int> localSpan = stackalloc int[size];
        localSpan[0] = value;
        return localSpan;    // CS8352
    }                        // localSpan refers to stack memory that's been reclaimed.

    static public void Main()
    {
        Span<int> localSpan = CreateSpanWithValue(5, 10);
        localSpan[2] = 14;
        foreach(var item in localSpan)
        {
            Console.WriteLine(item.ToString());  // Reading from deleted object
        }
    }
    // Example of output:
    // 284945320
    // 149
    // 149
    // 1369466325
    // 284945320
}

The following sample moves the stack allocation so its scope matches the Span.
This example solution works, because the memory Span refers to is allocated on the stack, but in the calling context:

C#
class Program
{
    static public void FillSpanWithValue(Span<int> span, int value)
    {
        span[0] = value;
    }

    static public void Main()
    {
        Span<int> localSpan = stackalloc int[5];
        FillSpanWithValue(localSpan, 10);
        localSpan[2] = 14;
        foreach(var item in localSpan)
        {
            Console.WriteLine(item.ToString());
        }
    }
    // Output:
    // 10
    // 0
    // 14
    // 0
    // 0
}

The following sample uses the new keyword to create the object on heap, instead of stack.
This example solution works, because after returning from CreateSpanWithValue method the memory that Span refers to is still valid as it is allocated on the heap, not on a stack:

C#
class Program
{
    static public Span<int> CreateSpanWithValue(int size, int value)
    {
        Span<int> localSpan = new int[size];
        localSpan[1] = value;
        return localSpan;
    }

    static public void Main()
    {
        var span = CreateSpanWithValue(5, 10);
        span[2] = 14;
        foreach(var item in span)
        {
            Console.WriteLine(item.ToString());
        }
    }
    // Output:
    //0
    //10
    //14
    //0
    //0
}

See also