7

I know strings are immutable, so the minute you change a string reference's value .NET makes a brand new string on the heap.

But what if you don't change the value of a string reference; rather, you simply pass it into a function ByVal -- does this operation copy the string value on the heap as well? My inclination is "no," but I'd like to confirm.

For example:

Public Function IsStringHello(ByVal test As String) As Boolean 
  Return (String.Compare(test, "Hello") = 0)    
End Function

Calling program:

Dim myWord as String = "Blah"
Dim matchesHello as Boolean = IsStringHello(myWord)

I know passing myWord by value makes a copy of the reference to "Blah", but since I have not tried to change the string itself, would it make another copy of the string on the heap?

Dan F
  • 11,958
  • 3
  • 48
  • 72
Rob Sobers
  • 20,737
  • 24
  • 82
  • 111
  • Why do people compare strings in this odd way ... http://stackoverflow.com/questions/859005/string-comparison-performance/859078 – Dario Jun 27 '09 at 12:56
  • 1
    Using String.Compare lets you specify case sensitivity. This might be clearer than uppercasing strings before comparing them. – Rob Sobers Jul 02 '09 at 20:14

6 Answers6

9

By the way, string interning is completely unrelated to that. The rule for passing parameters to functions is the same for all reference types (and really, all types), no matter how they are managed internally.

The rule is simple and you have stated it correctly: pass by value copies the reference, not the target. No heap space is copied here.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • interning is not directly related. You said: The rule is the same for all reference types (and really, all types), no matter how they are managed internally - I think you say it for copy of reference & not interning. right? – shahkalpesh Jun 26 '09 at 18:58
4

No. it still uses the copy of the reference to the "Blah".
What makes you think, it will?

On a side note, string are interned.

string s = "hello";
string t = "hello";

s & t both refer to the same string (because it is interned). If you modify s or t, it will create a new string, then.

shahkalpesh
  • 33,172
  • 3
  • 63
  • 88
  • I had a strange (foolish?) thought maybe merely making a copy of a reference to an immutable object caused a copy of the object itself, too. I strongly suspected that this was NOT the case, but I wanted to confirm. Great side-note about the "interning" of strings -- I did not know that. Thanks! – Rob Sobers Jun 26 '09 at 18:53
  • String *constants* are interned. Strings you create in other ways aren't interned. – Jon Skeet Jun 26 '09 at 18:56
  • @JonSkeet - ahhh...so in shahkalpesh's answer above where we assign two references to the same string *literal* does not mean they refer to the same string on the heap? – Rob Sobers Jun 26 '09 at 18:58
  • 1
    @Jon: if string s = "hello"; string t = "ello"; string z = "h" + t; do s & z point to same instance? – shahkalpesh Jun 26 '09 at 19:04
  • what does it mean by internedf? – user4234 Oct 14 '15 at 21:09
  • @SharenEayrs: Please see https://msdn.microsoft.com/en-us/library/system.string.intern%28v=vs.110%29.aspx. Also, https://en.wikipedia.org/wiki/String_interning – shahkalpesh Oct 15 '15 at 07:35
2

Passing objects ByVal creates a copy of the pointer, not the object itself. Here's a demonstration:

Module Module1
    Dim original As String = "Hello world"

    Sub PassByReferenceTest(ByVal other As String)
        Console.WriteLine("object.ReferenceEquals(original, other): {0}", _
            Object.ReferenceEquals(original, other))
    End Sub

    Sub Main()
        PassByReferenceTest(original)
        Console.ReadKey(True)
    End Sub
End Module

This program outputs the following:

object.ReferenceEquals(original, other): True

So, the original string and the string we passed by value exist at the same address in memory address. You're not making a copy of the string itself.

Juliet
  • 80,494
  • 45
  • 196
  • 228
0

Is short, no. It passes a ref to the string. Only one instance of the string itself.

Scott Weinstein
  • 18,890
  • 14
  • 78
  • 115
0

string is a reference type. If you pass it by value, what you are passing is the value of the reference.

The only way you'd get another copy on the heap would be to change the variable's value.

jlembke
  • 13,217
  • 11
  • 42
  • 56
0

A variable of type System.String effectively holds an "object-ID". Suppose that Object #1934 is a string with the characters "Blah", and you say Dim myWord As String = "Blah". The compiler will then store Object #1934 into myWord. Calling IsStringHello(myWord) would then cause that function to be called with its test parameter equal to Object #1934. In your example, there would be two variables of type System.String in memory--myWord and test, and both would hold the content Object #1934.

supercat
  • 77,689
  • 9
  • 166
  • 211