ubyte[] to string with @nogc - different behaviors

Steven Schveighoffer schveiguy at gmail.com
Wed Aug 5 18:46:19 UTC 2020


On 8/5/20 2:17 PM, Luhrel wrote:
> extern(D) string readString(ref const(ubyte)[] buffer) @nogc nothrow
> {
>      Array!ubyte bytes;

Array is a reference counted type -- at the end of this scope, if there 
are no more references to it, it will *free the memory* being used.

> 
>      ubyte b = buffer.read!ubyte();
>      while (b)
>      {
>          bytes.insertBack(b);
>          b = buffer.read!ubyte();
>      }
> 
>      if (bytes.length())
>      {
>          import core.stdc.stdio : printf;
>          import core.stdc.stdlib;
> 
>          char* str_ptr = cast(char*)malloc(bytes.length() * ubyte.sizeof);
>          string str = cast(string)str_ptr[0 .. bytes.length()];
>          str = cast(string)bytes[];

Adam is right, you are not copying data here, just reassigning the 
reference.

Not only that, but the expression bytes[] is not just a simple array, 
it's a range. I don't know what this does, but I wouldn't trust it.

What you likely want is:
str[] = bytes.data[];

This will copy all the data from the Array to the string.

However, I don't really understand the point of this function. What does 
buffer.read!ubyte do?

If you have a more descriptive statement on what you want to accomplish, 
I'm sure it can be done in a simpler way than what you are trying to do 
here.

> 
>          printf("String: %s\tLength: %lld\n", str.ptr, bytes.length);  
> // Works
> 
>          return str;
>      }
>      return null;
> }

At this point the data used by bytes (and therefore pointed at by str) 
are freed. So you are returning a dangling pointer here.

-Steve


More information about the Digitalmars-d mailing list