Use of freed value in iteration - how to workaround?

A

A. Farber

Hello,

I poll() over TCP-connected clients and sometimes
have to remove them. The following code works ok
for me (since many months):

# add the new client
$pkg->add($tcpSocket) if $Poll->events($tcpSocket) & POLLIN;

for my $child (values %Kids) {
# XXX a child can get removed inbetween
next unless $child;

my $fh = $child->{FH};
my $mask = $Poll->events($fh);

if ($mask & (POLLERR | POLLHUP)) {
$child->remove();
} elsif ($mask & POLLIN) {
unless ($child->read()) {
$child->remove();
next;
}
} elsif ($mask & POLLOUT) {
unless ($child->write()) {
$child->remove();
next;
}
}
}

It probably works ok, because I only remove
the current element ($child) of the array.

Now I have new situation, that I sometimes
have to remove an other element of the array,
while I'm in the $child->read() method.

I've added next unless $child; above,
but still my script dies with the error:
"Use of freed value in iteration".

From searching I know, that this is because
I'm removing an element of an array
whil iterating over it.

But my question is, how could I workaround it?

Thank you
Alex
 
A

A. Farber

Instead of removing elements immediately, push them
onto another array. Once you're done iterating over
the "main" array, iterate over the "hit list" array
and remove the elements in it from the "main" array.

Good idea, thank you!
 
X

Xho Jingleheimerschmidt

A. Farber said:
Hello,

I poll() over TCP-connected clients and sometimes
have to remove them. The following code works ok
for me (since many months):

# add the new client
$pkg->add($tcpSocket) if $Poll->events($tcpSocket) & POLLIN;

for my $child (values %Kids) {
# XXX a child can get removed inbetween
next unless $child;

If the value has been removed from %Kids, $child will not magically turn
false. (And even if it did, the "next" would occur too late to help).
I don't understand the rest of what you are doing (your code seems to be
using objects, but you don't give any indication of what modules they
are objects of), but perhaps this could help:

foreach my $key (keys %Kids) {
next unless exists $Kids{$key};
my $child=$kids{$key};

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top