0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node{
    int num;
    int deg;
    struct node* nxt;
    struct node* prv;

};
typedef struct node node_t;


void push(node_t *head, node_t *last, int number, int degree){
    node_t *newNode = (node_t*)malloc(sizeof(node_t));
    newNode->num = number;
    newNode->deg = degree;

    newNode->nxt = NULL;
    newNode->prv = NULL;

    if(head == NULL){
        head = newNode;
        last = newNode;
    }
    else{
       
        last->nxt = newNode;
        newNode->prv = last;
        last = newNode;
    }
}

int main(){
    node_t *pol1 = NULL;
    node_t *pol1F=NULL;
    int dataNum, dataDeg;
    dataNum =1;
    dataDeg =2;
    push(pol1, pol1F, dataNum , dataDeg);
    printf("%d", pol1->num );
    free(pol1);
    free(pol1F);

    return 0;
}

When trying to print a number from node I get status -1073741819. In the function, as long as I know, it should associate head with pol1 and enter the first if, considering head = NULL. In the future I will add other nodes and create another "head" for a second linked list. How can I access data from pol1 ?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • The return code is `0xC0000005` which is an access-violation crash. Which means you attempted to dereference an invalid pointer. – Some programmer dude Dec 13 '21 at 13:13
  • Use the address sanitizer if you have it: [runtime error: member access within null pointer of type 'struct node_t'](https://godbolt.org/z/417Ees7eP) – Ted Lyngmo Dec 13 '21 at 13:14
  • 1
    That change you make to `head` in `push` does not make it out to `main` - you need to use a double-pointer there. – 500 - Internal Server Error Dec 13 '21 at 13:14
  • 2
    As a hint: Remember that function arguments in C are passed *by value*. That means when you call a function, the value of the arguments are copied in the argument variables of the function.Modifying those argument variables, like assigning to them, will not modify the original value used in the call. – Some programmer dude Dec 13 '21 at 13:14
  • https://stackoverflow.com/questions/766893/how-do-i-modify-a-pointer-that-has-been-passed-into-a-function-in-c might be interesting – Jabberwocky Dec 13 '21 at 13:19
  • 1
    You also have some other logical bugs in your code, that will lead to likely crashes. For example, what if there's only one node in the list and `head == tail`? What happens when you call `free(pol1F)` after `free(pol1)`? – Some programmer dude Dec 13 '21 at 13:20
  • C has some warts, but one nice thing about it is that (unless you make extraordinary effort that is beyond the scope of the language) after `node_t *pol1 = NULL; push(pol1, pol1F, dataNum , dataDeg);`, it is guaranteed that `pol1` is still NULL. The call to `push` cannot change the value of the variable. – William Pursell Dec 13 '21 at 13:26

1 Answers1

0

Since you want the node pointers in main to be changed by the call to push, you should pass the address of those pointers as arguments. That is how push can know what to change. As you currently have it, it will only modify the value of its local variables.

Secondly, to free up the memory at the end, you should not call free on both pointers, since they may point to the same node. And this is the case when you have only added one node to the list. On the other hand, if your list has more than 2 nodes, you'll need to also free those intermediate nodes. All in all, you should create a loop that visits each node and frees it. Or, why not, create a pop function that removes the tail node from the list. Then you can call that function repeatedly until the list is empty.

Finally, pol1 and pol1F are not very descriptive variable names. Why not just head and tail?

Here is a correction and some related functions you could use:

void push(node_t **head, node_t **last, int number, int degree) {
    node_t *newNode = malloc(sizeof(node_t));
    newNode->num = number;
    newNode->deg = degree;
    newNode->nxt = NULL;
    newNode->prv = NULL;

    if (*head == NULL) {
        *head = newNode;
        *last = newNode;
    } else {
        (*last)->nxt = newNode;
        newNode->prv = *last;
        *last = newNode;
    }
}

void pop(node_t **head, node_t **last) {
    if (*head == NULL) {
        return;
    }
    if (*head == *last ) {
        free(*head);
        *head = NULL;
        *last = NULL;
    } else {
        *last = (*last)->prv;
        free((*last)->nxt);
        (*last)->nxt = NULL;
    }
}

void clearList(node_t **head, node_t **last) {
    while (*head != NULL) {
        pop(head, last);
    }
}

void printList(node_t *head) {
    while (head != NULL) {
        printf("(%d, %d) ", head->num, head->deg);
        head = head->nxt;
    }
    printf("\n");
}

int main() {
    node_t *head = NULL;
    node_t *tail = NULL;
    push(&head, &tail, 1, 20);
    push(&head, &tail, 2, 18);
    push(&head, &tail, 3, 21);
    printList(head);
    clearList(&head, &tail);
    return 0;
}
trincot
  • 317,000
  • 35
  • 244
  • 286