ubyte[] to string with @nogc - different behaviors

Luhrel lucien.perregaux at gmail.com
Wed Aug 5 19:43:18 UTC 2020


On Wednesday, 5 August 2020 at 18:46:19 UTC, Steven Schveighoffer 
wrote:
> 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.
>

Oh, okay I see now.

>> 
>>      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.

It's a shortcut for bytes[0 .. bytes.length]

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

Nope. I use the Array struct from rt.utils.container.array, which 
doesn't have a `data` property.

>
> 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?
>

It returns the first ubyte in the `buffer`. Once read, the ubyte 
is deleted from `buffer`.

> 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.
>

I'm improving rt.backtrace.dwarf, specifically the 
readLineNumberProgram function, which is @nogc, the source of all 
my problems :D.

DWARF v5 have a special DW_LNCT_path tag, which can be in the 
form DW_FORM_string.
 From the spec: "A string is a sequence of contiguous non-null 
bytes followed by one null
byte." - Commonly called a C string.

So, I need to read all non-null bytes in the buffer, until I 
found one. But, as readLineNumberProgram is @nogc, it's kinda 
hard for me (I don't come from C/C++).


>> 
>>          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