Dafna
Dafna

Reputation: 181

Using pointers and address

I have the following C# code: (Updating the code/question) The code and the project are marked as unsafe

private struct MEMORY_BASIC_INFORMATION
        {
            internal uint BaseAddress;
            internal uint AllocationBase;
            internal uint AllocationProtect;
            internal uint RegionSize;
            internal uint State;
            internal uint Protect;
            internal uint Type;
        }


public unsafe static bool CheckForSufficientStack(long bytes)
{
    MEMORY_BASIC_INFORMATION stackInfo = new MEMORY_BASIC_INFORMATION();

    // originally was
    // IntPtr currentAddr = new IntPtr((uint)&stackInfo - 4096);

    GCHandle gh = GCHandle.Alloc(stackInfo, GCHandleType.Pinned);
    IntPtr p = gh.AddrOfPinnedObject();

    //now - this line passes compilation        
    IntPtr currentAddr = new IntPtr((uint)p - 4096);

    // build error in the below line
    VirtualQuery(currentAddr, ref stackInfo, sizeof(MEMORY_BASIC_INFORMATION));

   return ((uint)currentAddr.ToInt64() - stackInfo.AllocationBase) >
                   (bytes + STACK_RESERVED_SPACE);
}

and when I compile it I get the error: Cannot take the address of, get the size of, or declare a pointer to a managed type

This is a code I copied and I was actually surprised to know there is '&' in c# but then build failed.

Any idea how to resolve this?

The error is now for the last line when we do a sizeof(MEMORY_BASIC_INFORMATION)

Upvotes: 2

Views: 129

Answers (3)

Dan Byström
Dan Byström

Reputation: 9244

You must "pin" the object in memory first, to make sure that theGC won't move it while you use it:

GCHandle gh = GCHandle.Alloc(stackInfo, GCHandleType.Pinned);
IntPtr p = gh.AddrOfPinnedObject();

Get the size of the struct with:

Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))

Upvotes: 2

Dafna
Dafna

Reputation: 181

The original code from here http://joeduffyblog.com/2006/07/15/checking-for-sufficient-stack-space/ passed compilation when I wrote it inside a new class and not inside an existing class I already have... I have no idea why it passed....

Upvotes: 0

Patrick Hofman
Patrick Hofman

Reputation: 156978

In order to make it work you have to indicate you are using unsafe code in C# (since a miscalculation for example could end you up with an invalid address). This is enforced by the unsafe keyword.

unsafe
{
    IntPtr currentAddr = new IntPtr((uint)&stackInfo - 4096);
}

Also make sure your project settings have Unsafe code enabled.

Upvotes: 1

Related Questions