Home > Software design >  How exactly does a substring share its memory with the original string?
How exactly does a substring share its memory with the original string?

Time:12-03

The following code creates a string and then a substring from that string:

let x = "a quick brown fox jumped over the lazy dog"

let range = x.startIndex...x.index(x.startIndex, offsetBy: 6)
var substring = x[range]

From what I understand, substring should share its memory with the string x. But if I do:

substring.replaceSubrange(substring.startIndex...substring.startIndex, with: "t")

print(substring)
print(x)

I get the following output:

t quick
a quick brown fox jumped over the lazy dog

Which means that they don't share the same memory anymore.

So, how does the memory sharing thing work? Does the call to replaceSubrange make a defensive copy of the text "a quick" inside the substring object and then replace the first letter "a" with "t"?

Or is " quick" still shared with the original string x, but the new memory was allocated only for the first character "t"? As far as I know that shouldn't be possible, because arrays store their memory continuously.

So, at which point did substring stop sharing its memory with x?

CodePudding user response:

According to Apple's docs, Substring instance is the result of slice of a string. It shares its storage with the original string which it is store inside this SubString not the original.

First, you need to know just like your example x is a String which is a value not a class. So it shares its memory with this x will and never happend.

When you create a Substring it automatically copy the value of your x which is a quick brown fox jumped over the lazy dog into a type Slice<String> as base and return back to you a Substring which is String.SubSequence of this own Slice<String>. And this base share its storage with Substring and no connection with the original x

Because of that, when ever you change the value x not making the value of this Slice<String> change too.

Example like this

var x = "a quick brown fox jumped over the lazy dog" // your original string

let range = x.startIndex...x.index(x.startIndex, offsetBy: 6)
var substring = x[range] // copy your original and combine with start index and end index

print("first substring: ", substring) // your desire result
print("base of substring: ", substring.base) // the value of x when clone into when creating substring

x = "abcder" // changing value x

print("second substring: ", substring) // still the same
print("base of substring: ", substring.base) // still the same
  • Related