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

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

void init(node* head, node* tail){
    head = (node*)malloc(sizeof(node));
    tail = (node*)malloc(sizeof(node));
    head->next = tail;
    tail->next = tail;
}

void push(node* head, int data){

    node *temp;
    temp = (node*)malloc(sizeof(node));

    if(temp == NULL){
        printf("%s", "Out Of Memory");
    }else{
        temp->data = data;
        temp->next = head->next;

on the next Line, there there's printf method which print number 7. It's for debug. but this printf methods didn't worked. so I noticed

temp->next = head->next; 

this code has an error. but I couldn't find the reason.. I was thinking of memory allocation issue. but still didn't get it..!

        printf("%d", 7);
        head->next = temp;
        printf("push (%d)", data);
    }
}

void main(){
    node* head = NULL;
    node* tail = NULL;
    init(head, tail);
    push(head, 10);
}
Noder
  • 313
  • 3
  • 15
  • 1
    There is nothing wrong with having an `init` function, but understand when passing a pointer to a function, the function receives a **copy of** the pointer (with its very own and very different pointer address). So if you need to pass-and-allocate a pointer without returning-and-assigning the new memory address, you need to pass the **address of** the pointer as a parameter (e.g. `node**`, and calling with `init(&head, &tail);`) so that you operate on the same pointer in your `init` function. Otherwise you allocate and assign the new address to a copy and the change is never seen in `main()`. – David C. Rankin Jun 16 '18 at 06:48
  • 1
    `printf("%s", "Out Of Memory")` -> `printf("Out Of Memory")` no need for `"%s"` – ThunderWiring Jun 16 '18 at 07:18
  • 1
    temp->next = head; – purec Jun 16 '18 at 08:19

3 Answers3

3
void init(node** head, node** tail){
    *head = malloc(sizeof(node));
    *tail = malloc(sizeof(node));
    (*head)->next = *tail;
    (*tail)->next = *tail;
}

void main(){
    node* head = NULL;
    node* tail = NULL;
    init(&head, &tail);
    push(head, 10);
}

You should pass head and tail as pass by reference to reflect the changed values of head and tail in calling function main().

For more information on pass by reference check this

Soumen
  • 1,068
  • 1
  • 12
  • 18
  • 2
    Your answer is correct, but note, there is no need to cast the return of `malloc`, it is unnecessary. See: [Do I cast the result of malloc?](http://stackoverflow.com/q/605845/995714) And... technically, you are not passing by reference -- there is no such thing in C, you are passing the **address of** the `head` and `tail` pointers by value `:)` – David C. Rankin Jun 16 '18 at 06:39
  • 1
    @DavidC.Rankin Yes, true indeed. – Soumen Jun 16 '18 at 06:42
1

1) You don't need nor want an initialization function. The stack is considered empty when head is NULL. So head = NULL; is sufficient initialization.

2) A stack don't need a tail pointer as elements are always inserted/removed at the front

3) Your push function must allow for update of head One way is to return the new head. Another is to pass a pointer to head

4) A linked list doesn't have tail->next = tail; The end of the list is reached when next is NULL. So if you have a tail it would be tail->next = NULL;

A stack using "return of new head" is more like:

node* push(node* head, int data){

    node *temp = malloc(sizeof(node));

    if(temp == NULL){
        printf("%s", "Out Of Memory");
        return head;
    }

    temp->data = data;
    temp->next = head;   // notice this
    return temp;
}

int main(){
    node* head = NULL;
    head = push(head, 10);
    return 0;
}

And a stack using "pass pointer to head" is more like:

void push(node** headPtr, int data){

    node *temp = malloc(sizeof(node));

    if(temp == NULL){
        printf("%s", "Out Of Memory");
        return;
    }

    temp->data = data;
    temp->next = *headPtr;   // notice the *
    *headPtr = temp;
}

int main(){
    node* head = NULL;
    push(&head, 10); // notice the &
    return 0;
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
1

You can remove the init function all together from your code and the tail is not necessary. If you want to use it for debugging, your main can look like this.

node* head = NULL;
node* tail = NULL;
head = (node*)malloc(sizeof(node));
tail = (node*)malloc(sizeof(node));

head->next = tail;
tail->next = tail;
akhil7886
  • 11
  • 3