www.digitalmars.com         C & C++   DMDScript  

D - Assigning Arrays & Garbage Collection

reply Russ Lewis <russ deming-os.org> writes:
Quick question...how does the garbage collector handle this code:



/* global variables */
int[] buf;
int *ptr;

void foo()
{
    int[5] temp = {1,2,3,4,5};
    ....
    buf = temp[2..4];
    ptr = &temp[2];
};



IIRC, arrays (like classes) are automatically created on the heap, not
the stack.  If that's wrong, then the whole example is nonsense.

Apparently, this code would set buf to point at 3 of the elements of the
temp array.  Since buf is set (not buf[]), then buf should point into
the temp array.  Similarly, ptr points into the array.  When foo()
returns, the var temp goes away, but we must not garbage-collect the
array yet until buf is set to some other location.

Trick is, neither the dynamic array buf nor the pointer ptr contain
pointers to the actual garbage-collectable object that they refer to.
Both contain pointers to elements *inside* that.  How does the garbage
collector handle this?

My ideas:
* Keep an extra pointer in each pointer and array that points to the
"root" object of the collection.  That's a MAJOR memory hit.
* When reassigning a pointer (or it goes out of scope) and you have to
"release" the object, search through a table of addresses to find which
object the pointer is "inside" of.  That's not a memory hit, but is a
potentially very significant speed hit.
Sep 05 2001
next sibling parent "Walter" <walter digitalmars.com> writes:
Russ Lewis wrote in message <3B971B87.A7AA67 deming-os.org>...
Trick is, neither the dynamic array buf nor the pointer ptr contain
pointers to the actual garbage-collectable object that they refer to.
Both contain pointers to elements *inside* that.  How does the garbage
collector handle this?

You've made an astute observation about GC. Many languages solve the problem by disallowing interior pointers. I thought such was too great a restriction, so the GC scans for interior pointers to any part of an allocated object, not just to the start of it. The way I set up the GC, it is not a significant performance hit, and has no extra memory requirements.
Sep 06 2001
prev sibling parent reply a <a b.c> writes:
	I don't know why, but I though that the assignment to buf was a copy
and not a reference.  If this is an alias, how would I copy it?

int[] foo(){
	int[] buf;
	int[5] temp = {1,2,3,4,5};
	// schtuff happens here
	buf = temp[2..4];
	return buf;
}

Dan 


Russ Lewis wrote:
 
 Quick question...how does the garbage collector handle this code:
 
 /* global variables */
 int[] buf;
 int *ptr;
 
 void foo()
 {
     int[5] temp = {1,2,3,4,5};
     ....
     buf = temp[2..4];
     ptr = &temp[2];
 };
 
 IIRC, arrays (like classes) are automatically created on the heap, not
 the stack.  If that's wrong, then the whole example is nonsense.
 
 Apparently, this code would set buf to point at 3 of the elements of the
 temp array.  Since buf is set (not buf[]), then buf should point into
 the temp array.  Similarly, ptr points into the array.  When foo()
 returns, the var temp goes away, but we must not garbage-collect the
 array yet until buf is set to some other location.
 
 Trick is, neither the dynamic array buf nor the pointer ptr contain
 pointers to the actual garbage-collectable object that they refer to.
 Both contain pointers to elements *inside* that.  How does the garbage
 collector handle this?
 
 My ideas:
 * Keep an extra pointer in each pointer and array that points to the
 "root" object of the collection.  That's a MAJOR memory hit.
 * When reassigning a pointer (or it goes out of scope) and you have to
 "release" the object, search through a table of addresses to find which
 object the pointer is "inside" of.  That's not a memory hit, but is a
 potentially very significant speed hit.

Sep 06 2001
parent reply Russ Lewis <russ deming-os.org> writes:
a wrote:

         I don't know why, but I though that the assignment to buf was a copy
 and not a reference.  If this is an alias, how would I copy it?

 int[] foo(){
         int[] buf;
         int[5] temp = {1,2,3,4,5};
         // schtuff happens here
         buf = temp[2..4];
         return buf;
 }

 Dan

Copy syntax is: buf[] = temp[2..4]; It attempts to communicate that "the elements of" buf are set to the array, rather than buf itself being set.
Sep 07 2001
parent reply Russ Lewis <russ deming-os.org> writes:
Russ Lewis wrote:

 a wrote:

         I don't know why, but I though that the assignment to buf was a copy
 and not a reference.  If this is an alias, how would I copy it?

 int[] foo(){
         int[] buf;
         int[5] temp = {1,2,3,4,5};
         // schtuff happens here
         buf = temp[2..4];
         return buf;
 }

 Dan

Copy syntax is: buf[] = temp[2..4]; It attempts to communicate that "the elements of" buf are set to the array, rather than buf itself being set.

Although it occurs to me that the copy-value syntax is supposed to only work when both array slices are the same size. That is, if buf was a static array with 3 elements, or a dynamic array with 3, I'm pretty sure it would work. I don't know what happens if the length is other than 3. Is the array resized? Also, I'm not clear on the precise status of an uninitialized dynamic array.
Sep 07 2001
parent "Walter" <walter digitalmars.com> writes:
"Russ Lewis" <russ deming-os.org> wrote in message
news:3B987A97.739EA762 deming-os.org...
 Although it occurs to me that the copy-value syntax is supposed to only

 both array slices are the same size.  That is, if buf was a static array

 elements, or a dynamic array with 3, I'm pretty sure it would work.  I

 what happens if the length is other than 3.  Is the array resized?

It's an error if the range sizes don't match.
 Also, I'm not clear on the precise status of an uninitialized dynamic

It's set to length 0.
Sep 07 2001