3

I am new to C. I set up a linked list like this:

#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

#define len(array) (sizeof(array) / sizeof(array[0]))

#define true 1
#define false 0

struct node{
    int data;
    struct node* next;
};

typedef struct node node;

node* initNode(void){
    node* headNode;
    headNode = (node *)malloc(sizeof(node));
    headNode -> next = NULL;
    return headNode;
}

node* create(int* array, int length){
    node* newNode;
    node* lastNode;
    node* headNode = initNode();
    newNode = (node *)malloc(sizeof(node));
    headNode -> data = array[0];
    int arrayLength = 1;
    int hasSetHead = false;
    while(arrayLength < length){
        if (! hasSetHead){
            lastNode = headNode;
            hasSetHead = true;
        }
        memset(newNode, 0, sizeof(node));
        newNode -> data = array[arrayLength];
        newNode -> next = NULL;
        lastNode -> next = newNode;
        lastNode = newNode;
        newNode = (node *)malloc(sizeof(node));
        if (newNode == NULL) exit(0);
        arrayLength++;
    }
    return headNode;
}

void clear(node* headNode){
    node* nextNode;
    if (headNode == NULL) return;
    while (headNode -> next != NULL){
        nextNode = headNode -> next;
        free(headNode);
        headNode = nextNode;
    }
    *headNode = NULL;
}

int main(void){
    int array[] = {1,2,3,4,5,6,7};
    int length = len(array);
    node* list = create(array, length);
    clear(list);
    system("pause");
    return true;
}

I want to clear my struct by use clear(struct pointer). But in last line of clear(), I got this error:

error: incompatible types in assignment

What should I do? Thank you! And please forget my poor English.

Thanks! @Marievi I've changed code like this:

headNode = NULL;

But when I want to print the linked list. It seems broken, here is my code:

void clear(node* headNode){
    node* nextNode;
    if (headNode == NULL) return;
    while (headNode -> next != NULL){
        nextNode = headNode -> next;
        free(headNode);
        headNode = nextNode;
    }
    *headNode = NULL;
}

When I called this function, it seems leak.

桂小方
  • 41
  • 1
  • 2
  • 6

4 Answers4

1

Change line :

*headNode = NULL;

to :

headNode = NULL;

and the error will disappear.


Also, do not cast the result of malloc and always check if malloc was successful.

Community
  • 1
  • 1
Marievi
  • 4,951
  • 1
  • 16
  • 33
1

Given headNode declared in your function as

node* headNode

, which is equivalent to

struct node *headNode

because of the in-scope typedef for type node. The problematic assignment

*headNode = NULL;

is attempting to assign the value NULL, a null pointer constant of type void *, to the object designated by *headNode, which is a struct node. You cannot assign a pointer value to an object of a structure type, which is what the error tells you.

You could assign NULL to headNode itself ...

headNode = NULL;

... as in fact another answer observes, but although the compiler will accept that, it will not have the effect you're after, because the headNode function parameter is local to the function. Its value is always a copy of the (pointer) value of its argument, and changes to the local copy do not affect the caller's original argument.

If you want the caller's copy to be changed then you have two main choices:

  1. Return the modified value (NULL) and let the caller assign it to the original variable if it wishes to do so, or

  2. Instead of passing the head pointer itself, pass a pointer to the variable containing the head pointer (of type node **).

Both alternatives will require changes in the caller; the latter will also require further changes to the function implementation.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
1

This line (after the '*' removal) does exactly nothing as it only changes the local headNode parameter ( and 100% will be removed completely by the compiler)

 headNode = NULL;

If you want to assign NULL to the higher level pointer you need to pass node **headnode to this function or make it node *:. 1.

void clear(node** headNode){
    node* nextNode;
    if (*headNode == NULL) return;
    while (*headNode -> next != NULL){
        nextNode = *headNode -> next;
        free(*headNode);
        *headNode = nextNode;
    }
    *headNode = NULL;
}

and the call

 clear(&list);

or better

node *clear(node* headNode){
    node* nextNode;
    if (headNode == NULL) return;
    while (headNode -> next != NULL){
        nextNode = headNode -> next;
        free(headNode);
        headNode = nextNode;
    }
    return NULL;
}

and the call :

list = clear(list);
0___________
  • 60,014
  • 4
  • 34
  • 74
0

The clear function is overly complicated and wrong. It doesn't free the last element.

This is correct:

void clear(node* headNode) {
  node* nextNode;

  while (headNode != NULL) {
    nextNode = headNode->next;
    free(headNode);
    headNode = nextNode;
  }
}

And if you want the clear function to set it's argument to NULL:

you need this:

void clear(node** headNode) {
  node* nextNode;

  while (*headNode != NULL) {
    nextNode = (*headNode)->next;
    free(*headNode);
    *headNode = nextNode;
  }

  *headNode = NULL;
}

and call it like this

clear(&list);
// now list is NULL
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115