www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is the `in` operator safe?

reply =?UTF-8?B?THXDrXM=?= Marques <luis luismarques.eu> writes:
After a quick look it seems like the `in` operator may return a 
pointer that becomes invalid when an AA is resized:

https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L601
https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L114
https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L193

Yet you can use `in` in  safe functions and keep the pointer 
around. Is my assessment correct, or did I overlook anything? If 
so, I'll open a bug report (I didn't find one already open for 
that, but maybe I searched the wrong keywords).
Feb 11 2019
next sibling parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Monday, 11 February 2019 at 21:47:05 UTC, Luís Marques wrote:
 After a quick look it seems like the `in` operator may return a 
 pointer that becomes invalid when an AA is resized:

 https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L601
 https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L114
 https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L193

 Yet you can use `in` in  safe functions and keep the pointer 
 around. Is my assessment correct, or did I overlook anything? 
 If so, I'll open a bug report (I didn't find one already open 
 for that, but maybe I searched the wrong keywords).
This quick test indicates that the pointer doesn't get invalidated: safe unittest { import std.stdio : writeln; int[int] arr; arr[0] = 0; int* p = 0 in arr; int n = 1; while (p == (0 in arr)) { if (n % 1000 == 0) n.writeln; arr[n++] = 0; } n.writeln; } It crashes with an OutOfMemoryError after allocating ~27M elements on my machine. It seems the AA is actually holding a list of Buckets, with each bucket containing a pointer to the actual element. When it's resize only the bucket list is affected, and the element pointers are still valid. -- Simen
Feb 11 2019
prev sibling next sibling parent Kagamin <spam here.lot> writes:
On Monday, 11 February 2019 at 21:47:05 UTC, Luís Marques wrote:
 After a quick look it seems like the `in` operator may return a 
 pointer that becomes invalid when an AA is resized
Memory allocated from GC is valid, that's how GC is part of the safety system.
Feb 12 2019
prev sibling parent Dukc <ajieskola gmail.com> writes:
On Monday, 11 February 2019 at 21:47:05 UTC, Luís Marques wrote:
 Yet you can use `in` in  safe functions and keep the pointer 
 around. Is my assessment correct, or did I overlook anything? 
 If so, I'll open a bug report (I didn't find one already open 
 for that, but maybe I searched the wrong keywords).
I believe the memory referenced to by AA is garbage collected, not memory managed by ownership. As long as the memory you keep the pointer at is scanned by the collector, the AA content should not get freed.
Feb 12 2019