Foreach Access Violation

nobody somebody at somewhere.com
Tue Oct 21 01:52:50 PDT 2008


module main;
import std.stdio;
class Apple
{
protected struct _Internal
{
int seeds;
}
private _Internal _intern;
this(int i)
{
_intern.seeds = i;
}
private void iterate()
{
writefln("iterate() apples[%s]",_intern.seeds);
//apple 3 kills apple 4, and apple 5 kills apple 6
if(_intern.seeds == 3 || _intern.seeds == 5)
{
apples[_intern.seeds+1].die();
}
}
private void die()
{
for (int i = 0; i < apples.length; i++)
{
if (apples[i] is this)
{
apples[i] = apples[$-1];
//uncommented: access violation error
//apples[$-1] = null;
apples.length = apples.length - 1;
writefln("die() apples[%s]",i);
delete this;
break;
}
}
}
}
Apple[] apples;

void main()
{
int n = 10; //nonstatic, random
for(int i = 0; i < n; i++)
{
apples ~= new Apple(i);
}
foreach(int i, Apple apple; apples)
{
//writefln("%s %s",i,apples.length);
apple.iterate();
//writefln("%s %s",i,apples.length);
}
}

/*
With apples[$-1] = null, without delete this
<OUTPUT>
iterate() apples[0]
iterate() apples[1]
iterate() apples[2]
iterate() apples[3]
die() apples[4]
iterate() apples[9]
iterate() apples[5]
die() apples[6]
iterate() apples[8]
iterate() apples[7]
Error: Access Violation
</OUTPUT>
Because of the foreach loop, this access violation makes sense.
Without apples[$-1] = null, with delete this
<OUTPUT>
iterate() apples[0]
iterate() apples[1]
iterate() apples[2]
iterate() apples[3]
die() apples[4]
iterate() apples[9]
iterate() apples[5]
die() apples[6]
iterate() apples[8]
iterate() apples[7]
iterate() apples[8]
iterate() apples[9]
</OUTPUT>
Because the array length is changed while in the foreach loop, the last 2 
lines show up.
However in my original code this also gives an access violation, and those 
last lines don't show up.
So possibly in this example code the delete this doesn't kick in, but in my 
longer original code it does?
*/ 




More information about the Digitalmars-d-learn mailing list