CurrentElement->next = CurrentElement->next->next (UNDEFINED?)

D

Deniz Bahar

Hi,

I'm working with a single linked list and want to delete elements by
searching through the list (starting form the HEAD) then finding the
element, then doing the following:

NewElement = CurrentElement->next;
CurrentElement->next = NewElement->next->next;
free(NewElement);

Does the double ->next invoke undefined behaviour (sequence points
etc)?



========
The full function follows:
========

typedef struct ElementTag Element;

extern Element *NewElement;
extern Element *CurrentElement;
extern Element *HeadElement;

/* Finds and deletes person- returns 1, returns 0 for failure) */
int
FindDeletePerson(const char *name)
{
if(!strcmp(HeadElement->Person.name, name))
{
NewElement = HeadElement->next;
free(HeadElement);
HeadElement = NewElement;
return 1;
}
else
{
CurrentElement = HeadElement;
while(CurrentElement->next)
{
if(!strcmp(CurrentElement->next->Person.name, name))
{
NewElement = CurrentElement->next;
CurrentElement->next = NewElement->next->next;
free(NewElement);
return 1;
}
CurrentElement = CurrentElement->next;
}
}
return 0;
}
 
Q

Quentarez

Hi,

I'm working with a single linked list and want to delete elements by
searching through the list (starting form the HEAD) then finding the
element, then doing the following:

NewElement = CurrentElement->next;
CurrentElement->next = NewElement->next->next;
free(NewElement);

Does the double ->next invoke undefined behaviour (sequence points
etc)?

<snip>

You can use as many ->next as you wish, as long as the ->next link exists.
 
A

Andrey Tarasevich

Deniz said:
...
I'm working with a single linked list and want to delete elements by
searching through the list (starting form the HEAD) then finding the
element, then doing the following:

NewElement = CurrentElement->next;
CurrentElement->next = NewElement->next->next;
free(NewElement);

Does the double ->next invoke undefined behaviour (sequence points
etc)?
...

No. Firstly, you are not accessing the same object twice.
'CurrentElement->next' as an lvalue is neither 'NewElement' nor
'NewElement->next' nor 'NewElement->next->next'. There's no problem with
sequence points here.

However, the code itself doesn't do what it is supposed to do. Doing

NewElement = CurrentElement->next;
CurrentElement->next = NewElement->next->next;

will exclude _two_ consecutive elements from the list (both 'NewElement'
and 'NewElement->next'), not one. Apparently, this is not what you
wanted to do. You probably intended to do either

NewElement = CurrentElement->next;
CurrentElement->next = NewElement->next;

or

NewElement = CurrentElement->next;
CurrentElement->next = CurrentElement->next->next;

That would exclude only one element from the list.

Now in that last version the value of 'CurrentElement->next' is accessed
twice (once to read it and once to modify it), which might rise the
question about sequence points etc. However, it this case everything is
fine too. The old value of 'CurrentElement->next' is read for the sole
purpose of determining its new value.
 

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,733
Messages
2,569,440
Members
44,831
Latest member
HealthSmartketoReviews

Latest Threads

Top