Thread overview
Gc/D_runtime prevents dangling pointers?
Jan 03
tipdbmp
Jan 04
thedeemon
Jan 04
tipdbmp
Jan 04
thedeemon
January 03
char * get_dangling_ptr() {
    char[] a;
    a.reserve(15);

    a ~= 'x';
    char *x = &a[0];

    auto a_initial_ptr = a.ptr;
    foreach (_; 0 .. 30) {
        a ~= 'y';
        //a.assumeSafeAppend() ~= 'y';
    }
    assert(a.ptr != a_initial_ptr, "a should've reallocated");

     // trying to reuse 'a's old memory
    foreach (_; 0 .. 10) {
        char[] b;
        b.reserve(15);
        foreach (__; 0 .. 15) {
            b ~= 'y';
        }
    }

    return x;
}

void main() {
    import std.stdio : writefln;
    char *x = get_dangling_ptr();
    writefln("ptr: %X; value: %s", x, *x);
}

x doesn't seem to be a dangling pointer, how come?

January 04
On Wednesday, 3 January 2018 at 22:22:06 UTC, tipdbmp wrote:

> x doesn't seem to be a dangling pointer, how come?

What is your definition of a dangling pointer?
In the shown example we have a reference to a piece of memory containing 'x', so this memory is not freed, it's used by the program. So when you access it via the pointer you get that 'x' value, everything's ok.
The comment also shows misunderstanding: when you allocate a new array you don't reuse the old memory, especially when it's still used, as it is here. This is how all GC'ed languages work: as long as you have live references to data, it's not freed and not reused. This makes all those references valid and not "dangling".
January 04
> What is your definition of a dangling pointer?
A pointer pointing to freed memory, which presumably '&a[0]' should be because it reallocates.

It seems that the '~=' operator "knows" that there's a reference to 'a's old memory and it keeps it around instead of freeing it.
I just don't understand the mechanism behind this.

January 04
On Thursday, 4 January 2018 at 11:05:25 UTC, tipdbmp wrote:
>> What is your definition of a dangling pointer?
> A pointer pointing to freed memory, which presumably '&a[0]' should be because it reallocates.

It allocates a larger array, but the old version is not freed up front. Right because there might be live references to the old data. Your pointer is such live reference. So while this pointer references that old version of the array, it's not freed. Only after no references are left the GC will make it free (and only when next GC cycle happens, not immediately).

> It seems that the '~=' operator "knows" that there's a reference to 'a's old memory and it keeps it around instead of freeing it.

It's just not its job to free that memory. That memory is freed later by GC, when it's safe to do so.
January 04
On 1/4/18 6:50 AM, thedeemon wrote:
> On Thursday, 4 January 2018 at 11:05:25 UTC, tipdbmp wrote:

>> It seems that the '~=' operator "knows" that there's a reference to 'a's old memory and it keeps it around instead of freeing it.
> 
> It's just not its job to free that memory. That memory is freed later by GC, when it's safe to do so.

Yeah, to further clarify, the array runtime has no idea who is looking at the memory. It doesn't "know" about references, it just relies on the GC to clean up the garbage if it actually is garbage.

-Steve