0

I want to create a linked list and keep two pointers. One for the head and one for the last element. I tried several approaches and just found a solution, but I don't know why my first solution don't work. The pointer in head->next always points on the last element, instead of the correct one.

int main(void){ // first solution

    struct pointList *lastElement;
    struct pointList *head;
    struct pointList headHelp = {.next = NULL, .p.x = 5, .p.y = 5};
    head = &headHelp;
    int i = 0;
    lastElement = &headHelp;
    for( i = 8; i < 10; i++){
        printf("LastElement: %d/%d\n", lastElement->p.x, lastElement->p.y);
        struct pointList *helpPoint;
        helpPoint = ((struct pointList*) malloc(sizeof(struct pointList)));
        struct pointList newElement = *helpPoint;
        newElement.next = NULL;
        newElement.p.x = i;
        newElement.p.y = i;

        lastElement->next = &newElement;
        lastElement = &newElement;
    }
    //printList(head);
    printf("LastElement: %d/%d\n", lastElement->p.x, lastElement->p.y);
    printf("head -> next: %d/%d\n", head->next->p.x, head->next->p.y);
    printf("finish\n");
    return 0;
}

output:

LastElement: 5/5
LastElement: 8/8
LastElement: 9/9
head -> next: 9/9
finish

but it should be : head -> next: 8/8 So the "next" pointer of head is changed in every loop execution

The solution which works looks like this:

int main(void){

    struct pointList *lastElement;
    struct pointList *head;
    struct pointList headHelp = {.next = NULL, .p.x = 5, .p.y = 5};
    head = &headHelp;
    int i = 0;
    lastElement = &headHelp;
    for( i = 8; i < 10; i++){
        printf("LastElement: %d/%d\n", lastElement->p.x, lastElement->p.y);
        lastElement->next = ((struct pointList*) malloc(sizeof(struct pointList)));

        lastElement->next->next = NULL;
        lastElement->next->p.x = i;
        lastElement->next->p.y = i;

        lastElement = lastElement->next;
    }
    //printList(head);
    printf("LastElement: %d/%d\n", lastElement->p.x, lastElement->p.y);
    printf("head -> next: %d/%d\n", head->next->p.x, head->next->p.y);
    printf("finish\n");
    return 0;
}

used struct:

struct pointList {
    struct point p;
    struct pointList *prev;
};
3
  • offtopic: Why are you mixing dynamic (malloc) memory with local memory in list nodes? Commented May 20, 2015 at 8:34
  • This: helpPoint = ((struct pointList*) malloc(sizeof(struct pointList))); really should be helpPoint = malloc(sizeof *helpPoint);. Way shorter, easier to read, less risk of error, and just ... well, better. Please don't cast the return value of malloc() in C. Commented May 20, 2015 at 8:57
  • @Telijas Should there be struct pointList *next instead of struct pointList *prev; in the structure definition? Commented May 20, 2015 at 9:05

1 Answer 1

1

The problem with the first code snippet is that you take and use the pointer to a local variable. The variable newElement have its scope inside the loop only, so when the loop iterates the current newElement variable goes out of scope and you are left with a stray pointer. This leads to undefined behavior.

You also allocate memory for helpPoint but you don't actually use it (when you initialize newElement using helpPoint you initialize one uninitialized structure with another uninitialized structure), and you do not free it anywhere leading to memory leaks.

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

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.