Amazing User
Amazing User

Reputation: 3563

How to know where memory is allocated for the reference and value type?

As I know if the int variable (value type) is declared directly within a class (reference type), the memory for the variable allocated on the heap.

But if there is a method in a class and the variable is declared inside a method, or is it an argument, the memory allocated on the stack.

public class A
{
    int x; // heap

    public void Func(int y) // stack
    {
        int z;  // stack
    }
}

How can I see, where memory is allocated?

Upvotes: 3

Views: 318

Answers (1)

Jeff
Jeff

Reputation: 2495

When you say 'where memory is located', I assume you mean the actual virtual address given to the variable, and perhaps the committed block or region which it resides in private bytes. While this trivial at best since it may be moved around (which is why native interop developers must pin the memory prior to use), you could hunt down the variable locations similar to the following:

Given the source (and breakpoint):

Source

Allow disassembly (Option-->Debugging-->General-->Show disassembly...) Right-Click (Context Menu): Select 'Go To Disassembly'

enter image description here

Note the assignment of z:

mov dword ptr [ebp-44h],eax

Open the registers window (Debug-->Windows-->Registers). Note the value of EBP (base pointer) == 0x05C0EF18.

Registers

Use calc (programmer mode) to determine [ebp-44h] from above. 0x05C0EF18 - 0x44 == 0x05C0EED4

Take a peek at that memory location (Debug-->Windows-->Memory-->Memory 1) Paste in the result value (0x05C0EED4 for this instance).

memory

Note the value

 87 d6 12 00 // <-- Little Endian  (00 12 d6 87 <-- Big Endian)
             //     0x0012D687 (hex) == 1234567 (decimal)

We can determine (for now) that z is located at 0x05C0EED4 and has 1234567 (decimal) stored in it's location.

A bit more complicated with x however. x is located at EAX+4.

// Similar exercise as above... 
// values get moved into registers, then the assignment...
mov eax,dword ptr [ebp-3Ch]  // [ebp-3Ch] == 0x05C0EF18 - 0x3C == 0x05C0EEDC 
                             // Move the value at 0x05C0EEDC (7c d4 40 02) to EAX
                             // [7c d4 40 02] (Big Endian) --> [02 40 d4 7c] (Little Endian)
                             // [02 40 d4 7c] (Little Endian) == 0x0240d47c or 37803132 (decimal)

mov edx,dword ptr [ebp-40h]  // [ebp-40h] == 0x05C0EF18 - 0x40 == 0x05C0EED8
                             // Move the value at 0x05C0EED8 (87 d6 12 00) to EDX
                             // [87 d6 12 00] (Big Endian) --> [00 12 d6 87] (Little Endian)
                             // [00 12 d6 87] (Little Endian) == 0x0012d687 or 1234567 (decimal)

mov dword ptr [eax+4],edx    // [EAX == 0x0240d47c] + 4 = 0x240D480
                             // Move the value at EDX (0x0012d687 or 1234567 (decimal)) to 
                             // EAX+4 (x variable located at 0x240D480)
                             //       (currently holds [b1 cb 74 00] (Big Endian)
                             //       which is equal to 7654321 (decimal)

memory memory memory

However, also interesting is the virtual memory map. Use vmmmap.exe from sysinternals to get a better picture of the reserved and committed pages. You can then poke around the different generations in the GC, etc.

Virtual Memory

Hope this helps!

Upvotes: 4

Related Questions