Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how does a swap method work in C# at a memory level?

I'm a Java programmer. I have little knowledge on C#. But from the blogs I have read, Java supports only pass-by-value-of-reference whereas in C# the default is pass-by-value-of-reference but the programmer can use pass by reference if needed.

I have penned down my understanding of how a swap function works. I guess it is crucial to get this concept clear as it is very fundamental to programming concepts.

In C#:

public static void Main()
{
  String ONE = "one"; //1
  ChangeString(ONE);  //2
  Console.WriteLine(ONE); //3

  String ONE = "ONE"; //4
  ChangeString(ref ONE); //5
  Console.WriteLine(ONE); //6
}

private static void ChangeString(String word)
{
  word = "TWO";
}
private static void SeedCounter(ref String word)
{
  word = "TWO";
}
  • Step 1: A string object with value one is created on heap and the address of its location is returned stored in variable ONE. Runtime Environment allocates a chunk of memory on the heap and returns a pointer to the start of this memory block. This variable ONE is stored on the stack which is a reference pointer to the locate the actual object in memory

  • Step 2: Method changeString is called. A copy of the pointer (or the memory address location) is assigned to the variable word. This variable is local to the method which means when the method call ends, it is removed from stack frame and is out of scope to be garbage collected. Within the method call, the variable word is reassigned to point to a new location where TWO object sits in memory. method returns

  • Step 3: Printing on the console should print ONE, since what was changed in the previous step was only a local variable

  • Step 4: Variable one is reassigned to point to the memory location where object ONE resides.

  • Step 5: method changeString is called. This time reference to the ONE is passed. what this means is the local method variable word is an alias to the variable one in the main scope. So, no copy of reference is done. Hence it is equivalent in thinking that the same variable one is passed to the method call. The method reassigns the variable to point to a different memory location which happens to hold TWO. The method returns

  • Step 6: Now the variable one on the outer scope i.e., in the main method is changed by method call and so it prints TWO.

In Java, step 5 is not possible. That is you cannot pass by reference.

Please correct if the programming flow I described above is correct?


Articles I have read, here and here.

like image 886
brain storm Avatar asked Sep 18 '14 20:09

brain storm


People also ask

How does the swap function work in C?

Swapping two number in C programming language means exchanging the values of two variables. Suppose you have two variable var1 & var2. Value of var1 is 20 & value of var2 is 40. So, after swapping the value of var1 will become 40 & value of var 2 will become 20.

Does C have swap?

The swap function is a typical operation to conduct on variables. There is no C standard library function that provides the feature like C++ has std::swap function.

How do you swap in programming?

In computer programming, the act of swapping two variables refers to mutually exchanging the values of the variables. Usually, this is done with the data in memory. For example, in a program, two variables may be defined thus (in pseudocode): data_item x := 1 data_item y := 0 swap (x, y);


1 Answers

You seem to understand the semantics correctly. Just to draw some analogies in other languages..

In C#, the default is an object reference (one level of indirection) except with value types. Passing by reference is essentially passing a pointer to an object reference, which is double indirection.

The closest is a C or C++ analogy.

C++

void ChangeString(std::string word)
{
  word = "TWO";
}

void SeedCounter(std::string &word)
{
  word = "TWO";
}

C (Ignoring issues of const, etc.)

void ChangeString(char * word)
{
  word = strdup("TWO");
}

void SeedCounter(char ** word)
{
  *word = strdup("TWO");
}

But a Java analogy would probably have to be a class with a string member:

public class StringRef
{
   public string val;
}

public static void ChangeString(string word)
{
  word = "TWO";
}

public static void SeedCounter(StringRef strRefWord)
{
  strRefWord.val = "TWO";
}

Elaborating per request.

In C# (or the CLR more specifically) a string variable is a pointer, but we refer to it as an object reference. The variable holds an address that points to a string object, usually somewhere on the heap. The variable itself is usually either a class field, where it likely exists on the heap, or a local variable or argument, so it exists on the stack or in a local variable slot (also on the stack). When you pass by reference, you are passing a pointer to your variable, not a pointer to the eventual object. Your "ref" param is A, A points to B which is your local variable or object field, and B points to C, the string object somewhere in memory. Passing by ref passes a A, which is a pointer to B, and you can now change B.

like image 176
codenheim Avatar answered Oct 12 '22 04:10

codenheim