35

I know that strings have variable length, therefore they need variable space in memory to be stored. When we define a string item in a struct, the struct's size would then be variable in length.

Older languages managed this by using fixed-length strings. However, there is no way to define fixed-length strings in C#, and C# manages normal strings in structs pretty good.

This becomes more weird when we define an array of such structs, or simply an array of strings. As result of any change (decrease/increase) in length of one string, all forward structs must be shifted.

How does C# handle variable-length strings in structs?

T.S.
  • 18,195
  • 11
  • 58
  • 78
h.nodehi
  • 1,036
  • 1
  • 17
  • 32

5 Answers5

59

The string itself is not stored in the struct. Instead a reference to the string is stored in the struct, so the struct size never changes.

string is not a value type; .NET strings are interned, which means that each unique string is stored in a look-up table in memory.

SSS
  • 4,807
  • 1
  • 23
  • 44
jjlin
  • 4,462
  • 1
  • 30
  • 23
  • Did you mean "Is a value type"? – Krythic Feb 18 '17 at 03:23
  • 7
    No, a string is not a [value type](https://msdn.microsoft.com/en-us/library/s1ax56ch.aspx). – jjlin Feb 18 '17 at 05:25
  • But the reference to the string is a value type? Correct? So a struct copies the ref(memory address) of the string on the heap. Your answer needs to be fixed. – Krythic Feb 18 '17 at 19:32
  • 9
    I'm not a C# language lawyer, but AFAIK, a C# reference itself doesn't have a type. You're correct that a reference behaves like a value type (e.g., you can't pass a reference to a reference the way you can pass a pointer to a pointer in C), but in my answer, "which is not a value type" is intended to modify "string" rather than "a reference [to the string]". I can understand how one might read it as the latter, but I think most people would read it as the former. In any case, now there's a long clarification in the comments. – jjlin Feb 19 '17 at 07:26
  • Read this as "reference (which is not a value type) to the string". Could definitely use a slight cleanup IMO – Joe Phillips Nov 28 '18 at 21:17
  • 2
    @jjlin Not all strings are interned as far as I remember: literal strings are interned by default, strings where `String.Intern()` is called are interned, but all the other are regular managed objects that can be garbage-collected I reckon. Also, in .NET it's safe to say that, no matter what, strings reside in the heap, so yup in a struct you'll have the reference to that heap location ;-) – Vince.Bdn Mar 16 '21 at 10:35
15

My first question to you would be, do your requirements dictate that a fixed length string is needed? If so a char[] might actually be what you are intending to use.

The .NET framework does not use C-style strings (char arrays) directly, but instead represents strings by immutable references. When a string is appended to or modified, you are actually creating a new string object in memory. This is a desired feature of the platform but one that requires consideration as expecting magically resizing strings can lead to some undesired side-effects.

Back to your question. "How does C# manage strings in structs?"

One of two ways to interpret this question from what I see:

1). How can I create structs that contain strings, and how does the .NET Framework manage strings in this scenario?

Short answer: keep in mind that strings are immutable types. Create your struct normally, and realize that the struct only contains a reference to the string, not a magically resizing segment of the struct that expands to include your volatile string.

2). How can the .NET Framework resize strings if they are a value type represented by structs.

Short answer, it doesn't. This isn't how .NET works with strings, see above.

Firoso
  • 6,647
  • 10
  • 45
  • 91
  • 1
    Thank you Firoso. No, I'm happy with strings. I was just concerned about the great time complexity of operations over structs and arrays of strings. Now I know the trick: "reference to the string". – h.nodehi Feb 17 '12 at 20:07
  • If you are concerned about the efficiency of strong manipulation and mutation, consider using the StringBuilder class. – Firoso Feb 17 '12 at 20:15
9

+1 to jjlin for a concise and accurate answer to the question, but a more general answer may be useful:

A field or variable declaration of any reference type represents a storage location for the reference. This is also true for fields of a struct.

(Including reference-type fields in a struct makes that type a "managed type", which is important in unsafe code; you can't declare a pointer to a managed type.)

phoog
  • 42,068
  • 6
  • 79
  • 117
4

C# manages strings in structs the way it manages strings in general. See:

Community
  • 1
  • 1
John Pick
  • 5,562
  • 31
  • 31
-7

Structure save in stack and string stores on heap.

Same as primitive types saves on stack and reference types saves on heap.

Tusharb
  • 11
  • 2