简体   繁体   中英

Dereferencing a pointer to a null pointer?

I'm trying to build a robust LinkedList in c, and one of the issues I am dealing with is initialization.

struct node* list = malloc(sizeof(node))

is an obvious way to initialize the LList, but it initializes the head element's value to 0, which is not exactly what I want. A newly initialized LList should not have any nodes in it. Instead, I'd like to do something like this:

struct node* list = NULL;

to create a LList, and then add elements with:

add(&list, 1);
add(&list, 2);

that would basically dereference &list , test to see if it is NULL , and if so do X otherwise do Y. However, obviously I am seg faulting, and am wondering if it is because I am dereferencing a pointer to a null pointer?

add()

  8 void add(struct node** headRef, int value) {
  9   struct node* node = *headRef;
 10   struct node* new_node = malloc(sizeof(*new_node));
 11 
 12   new_node->value = value;
 13   new_node->next = NULL;
 14 
 15   if (node == NULL) {
 16     node = malloc(sizeof(node));
 17     node = new_node;
 18   } else {
 19 
 20     while (node->next != NULL) {
 21       node = node->next;
 22     }
 23 
 24     node->next = new_node;
 25   }
 26 }

Thanks

This code has 3 problems:

node = malloc(sizeof(node));
node = new_node;

Firstly you malloc the wrong number of bytes. Use the pattern node = malloc(sizeof *node); .

Secondly this leaks memory: you point node at a freshly allocated block of memory. Then you point node at the object new_node is pointing at. This leaves no pointers to the allocated block.

Thirdly, node is a local variable to your function so this change is not seen by code outside your function.

I think you meant the entire function to be something like:

void add(struct node** headRef, int value)
{
// Make the new node
    struct node* new_node = malloc(sizeof *new_node);
    new_node->value = value;
    new_node->next = NULL;

// If the list is empty then make the new node be the first node
    if ( *headRef == NULL ) 
        *headRef = new_node;

// Otherwise put this node on the end of the list
    else for ( struct node *ptr = *headRef; ; ptr = ptr->next )
    {
         if ( ptr->next == NULL )
         {
              ptr->next = new_node;
              break;
         }
    }
}

Pointer is just a mechanism to access memory. Different types of pointers has different access mechanisms. Integer pointer reads 4 bytes while character pointer reads only one when you deference it.

For storing something, You need to allocate memory. Once you allocate memory, you can access it using different pointers. When you write :

  new_node=(struct node*)malloc(sizeof(struct node))

it means that you are allocating some memory and accessing it using new_node pointer.

When you write:

   node=new_node

it means that node will point to the same memory new_node is currently referring.You dont need to allocate memory to node since you are just accessing the already allocated memory using it.

void add(struct node** headRef, int value) {
    struct node* node = *headRef;
    struct node* new_node = malloc(sizeof(struct node));//Always mention datatype rather than mentioning a particular value;

    new_node->value = value;
    new_node->next = NULL;

    if (node == NULL) {
      //node = malloc(sizeof(node)); //Not required as you are just accessing the pre-allocated memory;

      *headRef = new_node; //Change the actual pointer rather than the local one;
    } else {

      while (node->next != NULL) {
        node = node->next;
      }

      node->next = new_node;
    }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM