-5

I know what passing by ref is and what it means, but what exactly happens with the objects passed by ref? Is it guaranteed that the objects stay at their current position in memory while the reference is being used?

Does it make a difference whether the variables are locals or not?

I'm mostly interested with what happens in memory.

A bit of background information: I have written a simple test program that stores the memory address of objects passed by ref and noticed how C# likes to move objects around in memory. But what I think is odd was that the objects being used were locals of a function. This automatically makes me think that the object's reference can't move in memory because it is on the stack. But clearly I'm missing something. What kind of memory was I receiving when using the ref?

Community
  • 1
  • 1
  • http://www.dotnetperls.com/parameter – user1666620 Jan 14 '16 at 15:06
  • 1
    Jon Skeet could (and probably has) written a chapter or two on this subject. – Brian Driscoll Jan 14 '16 at 15:06
  • @BrianDriscoll Jon Skeet corrected the .NET team after they first wrote it. ;) – krillgar Jan 14 '16 at 15:09
  • Read the [docs](https://msdn.microsoft.com/en-us/library/14akc2c7.aspx). Specifically on [using `ref` for reference types](https://msdn.microsoft.com/en-us/library/s6938f28.aspx) – ryanyuyu Jan 14 '16 at 15:09
  • http://www.yoda.arachsys.com/csharp/parameters.html – sll Jan 14 '16 at 15:10
  • 1
    _"I'm mostly interested with what happens in memory."_ -> this is an implementation detail of whatever runtime (technically which [Virtual Execution System](https://en.wikipedia.org/wiki/Virtual_Execution_System)) you're in. – James Thorpe Jan 14 '16 at 15:10
  • Maoni Stephens wrote a blog post addressing this: http://blogs.msdn.com/b/maoni/archive/2015/07/15/allocating-on-the-stack-or-the-heap.aspx – S. Rojak Jan 14 '16 at 15:10
  • I have reopened the question. I think that the question title was misleading, and I have taken the liberty to modify it to more closely match the *actual* question Jerry apparently wanted to ask. – Heinzi Jan 14 '16 at 15:55

1 Answers1

1

Let's look at an example:

static void callee(ref int y) { ... }

static void caller() 
{
    int x = 3;
    callee(x);
}

What exactly does it do with the objects passed by ref?

Nothing happens with the object. Passing a parameter by ref creates an alias, which means that x and y refer to the same storage location.

Does it guarantee the objects to stay at their current position in memory while the reference is being used?

No, there is no guarantee that the objects will stay at the same location in memory. It's possible that a particular implementation of the CLR decides not to move certain objects around, but it does that at its own discretion. You don't have a guarantee for that. You are only guaranteed that x and y always refer to the same storage location.

If you need to fix a storage location in memory, use the C# fixed Statement.

I'm mostly interested with what happens in memory.

That's an implementation detail of the particular C# runtime you are using. The contract is simple: If you use fixed, the location in memory is guaranteed to be fixed. If you don't, it isn't.

Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • If there is no guarantee then how is it supposed to work with unmanaged code in a DLL file? Or is it actually the case where it doesn't work, even with simple value types, unless you use the fixed keyword? I'm using Microsoft Visual C# 2010. – Jerry Hundric Jan 14 '16 at 15:42
  • @JerryHundric: In the case of unmanaged DLLs, the interop marshaller does all the hard work automatically: [It can copy or pin data as required.](https://msdn.microsoft.com/en-us/library/23acw07k(v=vs.110).aspx) You don't need to worry about it. – Heinzi Jan 14 '16 at 15:44
  • Yeah, I was hoping for something more along the lines of how it all works with unmanaged code since that is how I got my observation. If I pass by ref to unmanaged code and then pass by ref to a callback function, everything is fine. However, if I call an unmanaged function that first stores the ref value and then, once that function has returned, call another unmanaged function to pass the ref to the callback, I find that it won't work. I probably should have made it more clear that the question was aimed towards unmanaged code. – Jerry Hundric Jan 14 '16 at 16:02
  • @JerryHundric: Maybe a new question about a *specific* case with a [mcve] might be a good idea. It might get better reactions from the community than your current broad question and might even attract the unmanaged/interop specialists here (be sure to tag your new question appropriately so that they see it). – Heinzi Jan 14 '16 at 16:09