Thread overview
Deleting from Associate Array during foreach
Jul 09, 2004
Vathix
Jul 09, 2004
Russ Lewis
July 09, 2004
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?
July 09, 2004
"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.


July 09, 2004
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.

July 09, 2004
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];
>>>}