www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Deleting from Associate Array during foreach

reply "teqDruid (formerly DemmeGod)" <me teqdruid.com> writes:
Deleting stuff in an associative array while foreaching through it seems
to mess with the foreach.  Is this a bug, or am I doing something wrong?

John

void main()
{
	Object[Object] objects;
	
	for(int i=0; i<100; i++)
		objects[new Object()] = new Object();
	
	foreach(Object i, Object o; objects)
	{
		printf("deleting...\n\0");
		delete objects[i];
	}
}

Produces this output:
$ dmd dtest.d
gcc dtest.o -o dtest -lphobos -lpthread -lm
$ ./dtest
deleting...
deleting...
deleting...
deleting...
deleting...

If the delete line is commented out, a lot of "deleting..." lines are
produced.  I haven't counted, but I'd assume there's 100 of them.  Does
the array rehash after every 5, and break the foreach or something?
Jul 08 2004
parent reply "Vathix" <vathixSpamFix dprogramming.com> writes:
"teqDruid (formerly DemmeGod)" <me teqdruid.com> wrote in message
news:pan.2004.07.09.01.06.42.822388 teqdruid.com...
 Deleting stuff in an associative array while foreaching through it seems
 to mess with the foreach.  Is this a bug, or am I doing something wrong?

 John

 void main()
 {
 Object[Object] objects;

 for(int i=0; i<100; i++)
 objects[new Object()] = new Object();

 foreach(Object i, Object o; objects)
 {
 printf("deleting...\n\0");
 delete objects[i];
 }
 }

 Produces this output:
 $ dmd dtest.d
 gcc dtest.o -o dtest -lphobos -lpthread -lm
 $ ./dtest
 deleting...
 deleting...
 deleting...
 deleting...
 deleting...

 If the delete line is commented out, a lot of "deleting..." lines are
 produced.  I haven't counted, but I'd assume there's 100 of them.  Does
 the array rehash after every 5, and break the foreach or something?
You're not allowed to do it. "The aggregate itself must not be resized, reallocated, free'd, reassigned or destructed while the foreach is iterating over the elements." Loop the objects.keys instead.
Jul 08 2004
parent reply "teqDruid (formerly DemmeGod)" <me teqdruid.com> writes:
Missed that.  Thanks.

BTW, does anyone know what the behavior of (associative array).keys is? 
That is, should one be worried about changes being made the the
associative array is the array returned by .keys is changed?

TIA
John

On Thu, 08 Jul 2004 21:51:20 -0400, Vathix wrote:

 "teqDruid (formerly DemmeGod)" <me teqdruid.com> wrote in message
 news:pan.2004.07.09.01.06.42.822388 teqdruid.com...
 Deleting stuff in an associative array while foreaching through it seems
 to mess with the foreach.  Is this a bug, or am I doing something wrong?

 John

 void main()
 {
 Object[Object] objects;

 for(int i=0; i<100; i++)
 objects[new Object()] = new Object();

 foreach(Object i, Object o; objects)
 {
 printf("deleting...\n\0");
 delete objects[i];
 }
 }
 }
 Produces this output:
 $ dmd dtest.d
 gcc dtest.o -o dtest -lphobos -lpthread -lm $ ./dtest
 deleting...
 deleting...
 deleting...
 deleting...
 deleting...

 If the delete line is commented out, a lot of "deleting..." lines are
 produced.  I haven't counted, but I'd assume there's 100 of them.  Does
 the array rehash after every 5, and break the foreach or something?
You're not allowed to do it. "The aggregate itself must not be resized, reallocated, free'd, reassigned or destructed while the foreach is iterating over the elements." Loop the objects.keys instead.
Jul 09 2004
parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
I don't know.  Frankly, if it's not specified in the spec, then you 
shouldn't assume anything, either.

Although it will cost some performance, a sure-to-be safe thing to do 
would be

	foreach(Object; objects.keys.dup) { ... }

teqDruid (formerly DemmeGod) wrote:
 Missed that.  Thanks.
 
 BTW, does anyone know what the behavior of (associative array).keys is? 
 That is, should one be worried about changes being made the the
 associative array is the array returned by .keys is changed?
 
foreach(Object i, Object o; objects)
{
printf("deleting...\n\0");
delete objects[i];
}
Jul 09 2004