How does string works in c#? [closed]

笑着哭i 提交于 2019-12-14 03:38:27

问题


I know strings are inmutable, once created we cannot change it, I've read that if we create a new string object and we assign a value to it and then we assign another value to the same string object internally there is actually another object created and assigned with the new value. Let's say I have:

string str = "dog";            
str =  "cat";  

If I write Console.WriteLine(str); it returns cat. So internally there are two objects? But they have the same name? How does it works? I've made some research on google but I have not find yet something convincing enough to me so I can clarify my thoughts about this. I know strings are reference types, so we have an object in the stack with a reference to a value in the heap, what's happening in this case?(see code above).

I've upload a picture, apologize me if I'm wrong about the idea of the stack and the heap that's why I'm asking this question. Does the picture reflects what happens in the first line of code(string str = "dog";)? And then what should happen in the second line of code?? The dog value in the heap changes? And then a new object in the stack is created referencing it? Then what happens with the object that was there before? Do they have the same name? I'm sorry for so many questions but I think that is very important to understand this correctly and to know what's happening behind the scenes...


回答1:


review String Interning or .Net String Intern table or CLR Intern Pool.
Basically, the Common Language Runtime (CLR) maintains a table of [unique] string values, and whenever you manipulate a string in your code, the CLR examines this intern table to see if the new value you are trying to create is already in there or not. If it is, it just reassigns the variable you are modifying to point to that entry in the intern pool. If not, it adds the value to the pool and returns that new reference. Old values in the pool, no longer referenced by variables, get garbage collected.




回答2:


When you assign str to "dog", it does as you describe above in memory: the reference variable str now is "pointing at" the location of the string you've just instantiated.

str => MEMORY LOCATION "1": "dog"
       MEMORY LOCATION "2":
       MEMORY LOCATION "3":

When str is reassigned to your new string, "cat", it too is created in memory, and now str is adjusted so it points at "cat" in the new location.

       MEMORY LOCATION "1": "dog"
str => MEMORY LOCATION "2": "cat"
       MEMORY LOCATION "3":

What happens to "dog"? It's effectively inaccessible now, since we no longer have a reference to its location (in the memory, heap, terms are interchangeable in this situation). Later, when the Garbage collector reviews the memory for cleaning, it'll realize that there is nothing referencing "dog" and it will mark the memory for being deleted and replaced as needed.




回答3:


You're close. Your picture accurately represents what happens in the first line of code. However, things are a little different from what you describe for the second line of code.

For the line str = "cat";, a second string object is created in the heap and the str variable is changed to refer to that new object. You're left with str pointing to "cat" and an orphan "dog" object on the heap with no references to it.

The "dog" object might be cleaned up by the garbage collector because there are no references to it.




回答4:


Yes, there are two objects. No, they don't have the same name. Try not to think of a variable as a "name" for the object itself per se - it's more like a temporary name for the object's location in memory. (The reason it's somewhat misleading to think of a variable as a "name" for the object is that you can have several variables referring to the same object; it's not the case that the object has several "names" per se, or that there are several objects - that's just how you happen to be storing the reference).

"string str" initially has a reference to the string "dog." After you assign "cat" to "str", the variable now has a reference to the string "cat."

Both strings still exist in memory (at least temporarily), but the "dog" string is no longer accessible because you don't have a reference to it (and therefore no longer "know" its location). You don't know in advance how long they'll both exist in memory though since the garbage collector could delete the "dog" string from memory at any point since there are no longer any references to it.

You're correct about the value on the stack with the reference to the object on the heap by the way - that's a good distinction.



来源:https://stackoverflow.com/questions/38794835/how-does-string-works-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!