1

Pardon me,I am not very good in explaining questions. I can better explain my question through following example:

string first = "hello";
string second = "Bye";
first = second;

In the above example,consider the third line first=second .
Here i assigned object second to first. Because strings in c# are immutable i.e Every time you assign a new value to an existing string object, a new object is being created and old object is being released by the CLR.(I read this from here1). So simply it means the object first in first line is different from object first in third line.

So My question is how can i prove both are different?
i.e if it(string) is possible in C then i can print address of both objects before and after the third statement to prove it.
Is there any method to access there addresses or other alternatives are there?

A.s. Bhullar
  • 2,680
  • 2
  • 26
  • 32
  • 1
    In other words, you'd like to learn the memory address of `first` (before and after). I never needed it, but have a look at http://stackoverflow.com/questions/588817/c-sharp-memory-address-and-variable perhaps? – Konrad Morawski Oct 14 '13 at 06:49
  • "Every time you assign a new value to an existing string object,..." - you're not assigning to an existing string object. You're assigning to a *variable*. You need to distinguish between variables and objects. – Damien_The_Unbeliever Oct 14 '13 at 06:50

6 Answers6

5

If you'd like to see the physical location in memory, you can use the following (unsafe) code.

private static void Main(string[] args)
{
  unsafe
  {
    string first = "hello";

    fixed (char* p = first)
    {
      Console.WriteLine("Address of first: {0}", ((int)p).ToString());
    }

    string second = "Bye";

    fixed (char* p = second)
    {
      Console.WriteLine("Address of second: {0}", ((int)p).ToString());
    }

    first = second;

    fixed (char* p = first)
    {
      Console.WriteLine("Address of first: {0}", ((int)p).ToString());
    }
  }
}

Sample output on my machine:

Address of first: 41793976 
Address of second: 41794056
Address of first: 41794056

You'll notice, that .NET caches the string instances which is perfectly valid because they are immutable. To demonstrate this behavior, you can change second to hello and all memory addresses will be the same. That's why you shouldn't rely on native memory stuff and just use the managed ways to work with objects.

See also:

The common language runtime conserves string storage by maintaining a table, called the intern pool, that contains a single reference to each unique literal string declared or created programmatically in your program. Consequently, an instance of a literal string with a particular value only exists once in the system.

Source: String.Intern (MSDN)

Gene
  • 4,192
  • 5
  • 32
  • 56
3

I believe that you want the ReferenceEquals method. It can be used to check if two instances of the object are exactly the same - i.e. references the same object.

fredrik
  • 6,483
  • 3
  • 35
  • 45
1

*you can use the .Equals() method or HashCode() method to compare *

Mahmoud Hashim
  • 550
  • 5
  • 13
  • 1
    I don't think that's what the OP means. – Konrad Morawski Oct 14 '13 at 06:48
  • thanks,@Mahmoud hashim,but i can not use .Equals() because one of them(i.e object in first line )has been deallocated.And I don't know how to use HashCode()?Can you plz give any example? – A.s. Bhullar Oct 14 '13 at 06:50
  • 1
    @A.s.Bhullar hash code will not give you anything else than what you already know (namely that `"second" != "first"`) – Konrad Morawski Oct 14 '13 at 06:52
  • The default implementation of GetHashCode returns a hashcode based upon the reference. I've never seen it collide, but never used it in production code. – Gusdor Oct 14 '13 at 07:13
  • In MSDN they say that "different (unequal) objects can have identical hash codes" so it will not a safe way to solve this question Link :- http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx – Jageen Oct 14 '13 at 09:09
1

If you have to compare the underlying memory addreses, the following unsafe code might help you (untested):

string first = "hello";


GCHandle handle = GCHandle.Alloc(first, GCHandleType.Pinned);
IntPtr address = handle.AddrOfPinnedObject();


string second = "Bye";
first = second;


GCHandle handle = GCHandle.Alloc(first, GCHandleType.Pinned);
IntPtr address2 = handle.AddrOfPinnedObject();

if (address != address2)
{
    // memory addresses are different afterwards
}
Baldrick
  • 11,712
  • 2
  • 31
  • 35
1

You've misunderstood what you've read. Yes, strings are immutable. That means you cannot change an existing string. This won't work:

string x = "Hello";
x[3] = 'q';

When you're concatenating strings, you get a new one:

string a = "a";
string b = "b";
string c = a+b; // You get a new string and a and b are unchanged.

Even when you're self-concatenating, you get a new string:

string a = "a";
a += "b"; // The same as a = a + "b" and yields a new string.

But assigning to a variable (or passing to a function, or returning from a function, etc) does NOT create a new string.

Strings are "reference types". That means that this variable:

string a = "Hello";

Is just a reference to the string. Doing this:

string b = a;

Just assigns the reference to the variable. It does not alter the string.

Or, to put it in C terms: Reference variables are pointers to objects. Consider:

string a = "Hello"; // a now points to the string object
string b = a; // b now points to the same object.

What the immutability means is that you cannot change the memory that the pointer points to (the string object itself). But the pointer variable is as changeable as ever. You can assign a different address to it.

To return to your original example:

string first = "hello"; // Allocates memory for "hello" and points first to it.
string second = "Bye";  // Allocates memory for "Bye" and points second to it.
first = second;         // Assigns the address of second to first.

In the end, both first and second point to the same address, which is the address of the string Bye. The memory of the string hello is now unreferenced (there are no pointers to it, it's unreachable). The garbage collector will reclaim it sometime later.

Added: Yet another analogy with C. String variables .NET are somewhat like this:

const char* str;

It's a pointer to a constant. You can change the pointer, but you cannot change the stuff that it points to.

Added 2: You should read up on Value Types vs Reference Types in .NET. In a nutshell, value types are all struct types, and reference types are all class types. Value types get copied on assignment (or when passed/returned from a function); reference types are pointers.

Note that there is one unintuitive piece here. The class object, which is the base class of ALL types, is a reference type. Yet Value Types inherit from it, and you can assign a Value Type to a variable of type object. If you do it, this will cause something called boxing and it involves making a copy of the value, so it's a bit of an expensive operation.

Vilx-
  • 104,512
  • 87
  • 279
  • 422
1

for this you should get memory address of first first variable before assigning second to it and again check the memory address after assigning.

for getting the address of string follow this link

may this help you

Community
  • 1
  • 1
Vikash Singh
  • 804
  • 1
  • 10
  • 11