www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Gc/D_runtime prevents dangling pointers?

reply tipdbmp <email example.com> writes:
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?
Jan 03 2018
parent reply thedeemon <dlang thedeemon.com> writes:
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".
Jan 03 2018
parent reply tipdbmp <email example.com> writes:
 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.
Jan 04 2018
parent reply thedeemon <dlang thedeemon.com> writes:
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.
Jan 04 2018
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Jan 04 2018