On Tue, Dec 31, 2019 at 09:33:14AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: > On 12/30/19 6:31 PM, H. S. Teoh wrote: > > On Mon, Dec 30, 2019 at 03:09:58PM -0800, H. S. Teoh via > > Digitalmars-d-learn wrote: [...] > > Haha, it's actually right there in the Grapheme docs for the opSlice > > overloads: > > > > Random-access range over Grapheme's $(CHARACTERS). > > > > Warning: Invalidates when this Grapheme leaves the scope, > > attempts to use it then would lead to memory corruption. > > > > Looks like when you use .map over the Grapheme, it gets copied into > > a temporary, which gets invalidated when map.front returns. > > Somewhere we're missing a 'scope' qualifier... [...] > Then the original example should be fixable by putting "ref" in for > all the lambdas. > > But this is kind of disturbing. Why does the grapheme do this? The > original data is not scoped.
Honestly I have no idea, but glancing at the code in std.uni reveals that the returned slice is actually a wrapper object that contains a pointer to the parent Grapheme object. So if the parent was a temporary and goes out of scope before the wrapper does, we're left with a dangling pointer. > e.g.: > > writeln(" Text = ", gr1.map!((ref g) => g).joiner.to!string); [...] Unfortunately this doesn't work. Somehow the ref parameter doesn't match whatever it is std.algorithm.map is trying to pass to it. T -- They say that "guns don't kill people, people kill people." Well I think the gun helps. If you just stood there and yelled BANG, I don't think you'd kill too many people. -- Eddie Izzard, Dressed to Kill