Setting array length without initializing/reallocating.

Dukc ajieskola at gmail.com
Sun Dec 13 13:19:35 UTC 2020


On Saturday, 12 December 2020 at 00:53:09 UTC, Jonathan Levi 
wrote:
> Wow, there went several hours of debugging.
>
> Increasing the length of a slice, by setting its length, will 
> initialize the new elements and reallocate if necessary.
>
> I did not realize length was "smart", I guess I should have 
> guessed.
>
> Anyway, to work around this, and probably also be more clear, 
> create a new slice from the same pointer.
>
> `array = array.ptr[0..newLength];`

There is a big downside in doing that: the array will not check 
whether it's still referring to valid memory after the resize.

Your way is efficient in machine code, but in most cases it's 
highly unpractical to skip on memory safety to speed up code like 
this.

In the general case, this is a better way to resize arrays 
without reallocating:

```
@safe resizedWithin(T)(T[] arr, T[] within, size_t newSize)
{  if(newSize == 0) return arr[0..0];
    auto startIndex= &arr[0] - &within[0];
    return within[startIndex .. startIndex + newSize];
}

@safe void main()
{  import std;
    auto containerArray = iota(1000).array;
    auto array = containerArray[50 .. 60];
    array = array.resizedWithin(containerArray, 20);
    //[50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 
65,
    //66, 67, 68, 69]
    writeln(array);
}
```

Here, if you accidently gave too big new size for `array`, or 
`array` wasn't withing `containerArray` (except if `array.length 
== 0`), the program would immediately abort instead of making an 
invalid array.


More information about the Digitalmars-d mailing list