0

I am trying to implement a function makelinkedList which accepts the number of nodes in the linked List and returns the address of . The function printlinkedList prints the linked list.

I don't get a segmentation fault when I implement this code.

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

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

typedef struct node linkedList;

void printlinkedList(linkedList** head){
    linkedList* crawler = *head;

    while(crawler!=NULL){
        printf("%d -> ", crawler->data);
        crawler= crawler->next;
    }
    printf("|NULL|\n");
}

linkedList* makelinkedList(int size){

    linkedList* crawler = malloc(sizeof(linkedList));
    crawler->data = --size;
    crawler->next = NULL;
    linkedList* head = crawler;
    while(size > 0){
        crawler->next = malloc(sizeof(linkedList));
        crawler = crawler->next;
        crawler->data = --size;
        crawler->next = NULL;
    }
    printlinkedList(&head);
    return head;
}

int main(void) {
    // your code goes here
    linkedList* node = (makelinkedList(5));
    linkedList** head = &node;
    printf("from main\n");
    printlinkedList(head);
    return 0;
}

OutPut of the code given above:

4 -> 3 -> 2 -> 1 -> 0 -> |NULL|

But when I try to return the address of head (&head) I get a segmentation fault. The code that results in the fault is given below:

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

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

typedef struct node linkedList;

void printlinkedList(linkedList** head){
    linkedList* crawler = *head;

    while(crawler!=NULL){
        printf("%d -> ", crawler->data);
        crawler= crawler->next;
    }
    printf("|NULL|\n");
}

linkedList** makelinkedList(int size){

    linkedList* crawler = malloc(sizeof(linkedList));
    crawler->data = --size;
    crawler->next = NULL;
    linkedList* head = crawler;
    while(size > 0){
        crawler->next = malloc(sizeof(linkedList));
        crawler = crawler->next;
        crawler->data = --size;
        crawler->next = NULL;
    }

    return &head;
}

int main(void) {
    // your code goes here
    linkedList** head = (makelinkedList(5));
    printf("from main\n");
    printlinkedList(head);
    return 0;
}

Why can't I return the address of the head ?

  • 1
    Address of the local (and not static) pointer variable is not valid outside of the scope. – BLUEPIXY Dec 19 '15 at 08:36
  • 1
    The first version of your code was just fine.. no need to mess with it. You could pass a single-depth pointer to `print` though. – M.M Dec 19 '15 at 08:43

2 Answers2

3

head is a local variable. Local variables are destroyed when the function that contains them returns.

So after makelinkedList returns, your "pointer to head" no longer points to head, since it doesn't exist. Typically, local variables get overwritten pretty quickly once they're destroyed, since all local variables share the same space in memory (the "stack"). By the time you try to use your pointer-to-head, that space no longer contains what head contained, but has been reused to store something else.

user253751
  • 57,427
  • 7
  • 48
  • 90
0

As immibis explains in his answer, you cannot return the address of a local variable. But the good new is you do not need to return the address, returning the value of head is all you need. head is a pointer to the first element of the list, it carries all the information needed.

Indeed you can just pass head to printLinkedList as well after simplifying it to ljst take a pointer instead of a pointer to a pointer.

The real cause for confusion is the typedef struct node linkedList. The linkedList should really be just a pointer to the first node, but typedefing pointer types is even more confusing. You can use a simpler typedef and use pointers to nodes in all your functions:

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

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

typedef struct node node;

void printlinkedList(node *head) {
    node *crawler = head;

    while (crawler != NULL) {
        printf("%d -> ", crawler->data);
        crawler = crawler->next;
    }
    printf("|NULL|\n");
}

node *makelinkedList(int size) {        
    node *crawler = malloc(sizeof(node));
    crawler->data = --size;
    crawler->next = NULL;
    mode *head = crawler;
    while (size > 0) {
        crawler->next = malloc(sizeof(linkedList));
        crawler = crawler->next;
        crawler->data = --size;
        crawler->next = NULL;
    }       
    return head;
}

int main(void) {
    node *head = makelinkedList(5);
    printf("from main\n");
    printlinkedList(head);
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189