3

In my assignment, I have to write a function that takes as arguments a pointer to a "LNode" structure and an integer argument. Then, I have to not only add that integer into the linked list, but also put place it so that the list is in proper ascending order. I've tried several various attempts at this, and this is my code as of posting.

LNode*  AddItem(LNode  *headPtr, int  newItem)
{
    auto    LNode   *ptr = headPtr;

    ptr = malloc(sizeof(LNode));

    if (headPtr == NULL)
    {
        ptr->value = newItem;
        ptr->next = headPtr;
        return ptr;
    }
    else
    {

        while (headPtr->value > newItem || ptr->next != NULL)
        {
            printf("While\n"); // This is simply to let me know how many times the loop runs
            headPtr = headPtr->next;
        }
        ptr->value = newItem;
        ptr->next = headPtr;
        return ptr;
    }

}  // end of "AddItem"

When I run it, and try to insert say a 5 and then a 3, the 5 gets inserted, but then the while loop runs once and I get a segmentation fault.

Also I cannot change the arguments as it's part of a skeletal code for this project. Thanks to anyone who can help.

If it helps this is what the structure looks like

typedef struct  LNode
{
    int                 value;
    struct  LNode      *next;

} LNode;
2
  • Do you have experience with gdb yet? It would be instructive to step through the program as it runs and watch what all the variables are doing. Commented Apr 7, 2012 at 13:48
  • is headPtr your head node and ptr new node? Commented Apr 9, 2012 at 5:10

4 Answers 4

3

In your loop

while (headPtr->value > newItem || ptr->next != NULL)
    {
    printf("While\n"); // This is simply to let me know how many times the loop runs
    headPtr = headPtr->next;

you check whether the uninitialised ptr->next is (not) NULL. That is not sensible and may cause havoc if perchance the bit pattern in that part of ptr is not that of a NULL pointer, because you have an || in the condition, then the loop condition is always true and you run off the end of your list.

The || is wrong anyway, you need a &&, both conditions must hold, something is not NULL and a relation among the values must hold.

And, since you want the list in ascending order, you must traverse the list while the value in the list is smaller than the to-be-inserted value.

But you must stop before the pointed-to value becomes as large as or larger than the new value, because you must modify the next pointer of the node after which you insert the new value.

if (headPtr->value >= newItem) {
    ptr->value = newItem;
    ptr->next = headPtr;
    return ptr;
}
while(headPtr->next != NULL && headPtr->next->value < newItem) {
    headPtr = headPtr->next;
}
// Now headPtr is the node behind which the new item is to be inserted
ptr->value = newItem;
ptr->next = headPtr->next;
headPtr->next = ptr;
return ??

But what pointer will you return? If the new Item is the first in the list, you return a pointer to the first node. If you also want to do that if the new item is inserted later, you need to keep (a copy of) the original headPtr and return that.

Sign up to request clarification or add additional context in comments.

Comments

2

Your while loop condition is wrong. You never set ptr->next but you use it to check ptr->next!=NULL which means headPtr=headPtr->next goes wild in the loop. So you should set: ptr->next=NULL once you set its value.

You can also take these lines out and put it at the top:

   ptr->value = newItem;
   ptr->next = headPtr;

Try this:

LNode*  AddItem(LNode  *headPtr, int  newItem)
{
    auto    LNode   *ptr, *temp, *orghead;
    orghead = headPtr;
    int fl=0;
    ptr = malloc(sizeof(LNode));
    ptr->value = newItem;
    ptr->next = NULL;
    temp = ptr;

    if (headPtr == NULL)
        return ptr;
    else
        {

        while(headPtr != NULL && headPtr->value < newItem)
            {
            printf("While\n");
            fl =1;
            temp = headPtr;
            headPtr = headPtr->next;
            }
        temp->next = ptr;
        ptr->next = headPtr;
        if(fl) return orghead;
        else return temp;
        }

}  // end of "AddItem"

1 Comment

Still doing that some thing. I'm trying to draw a picture of the memory locations to try and make sense of it. The display function simply goes through the linked list so I doubt it's something with that, and even if it was I couldn't change that function anyway.
0

Your while loop goes until the end of your linked list, and your last element is null. Thus in your while condition you are dereferencing a null node (headPtr), this way getting the segmentation fault. I think you need to check whether your node is null or not like this:

while (headPtr != NULL && (headPtr->value > newItem || ptr->next != NULL))

1 Comment

Daniel Fischer has a better answer. :)
0

so true from all the above

while (headPtr->value > newItem || ptr->next != NULL)
        {
            printf("While\n"); // This is simply to let me know how many times the loop runs
            headPtr = headPtr->next;
        }

You are not checking null Condition for headPtr inside While

at this point

headPtr = headPtr->next;

headPtr->next can be null which makes your program to crash

bit more

LNode*  AddItem(LNode  *headPtr, int  newItem)
{

auto    LNode   *ptr = headPtr; ?

    ptr = malloc(sizeof(LNode));

    if (headPtr == NULL)
    {
        ptr->value = newItem;
        ptr->next = headPtr;
        return ptr;
    }

consider headPtr is not NULL, ptr is now pointing to some malloc heap ptr->next may or may not be NULL insuch case

while (headPtr->value > newItem || ptr->next != NULL)

will be un-predictable

may be you need to look at your logic a little more

see below for pseudo logic if you like

LNode* add_time(LNode *headptr , data){

    LNode   *ptr =  headptr, *temp;        

    temp = malloc(sizeof(LNode));

    if(!temp) 
      return ptr;

    temp->next = NULL;
    temp->value= data;

    if(ptr == NULL){ 
        /** There is no list**/
        ptr = temp;
        return ptr;
     }

    /* go to last node*/
    while(ptr->next)
        ptr = ptr->next;

    ptr->next = temp;

    return ptr;

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.