I am creating a new stack using linked list. I dont know why the TOP pointer is always pointing to NULL. I think I am not setting the top pointer correctly, or it is not visible outside the function.
#include "stdio.h"
#include "stdlib.h"
typedef struct StackItem
{
int itemValue;
struct StackItem* NextItemPtr;
}StackItem;
typedef struct Stack
{
struct StackItem *TOP;
}Stack;
int IsStackEmpty(StackItem *TOP)
{
if(TOP==NULL)
return 1;
}
void pushItem(StackItem *headPtr,int n)
{
StackItem* Newnode;
Newnode=(StackItem*)malloc(sizeof(StackItem));
Newnode->itemValue=n;
printf("Checking Head TOP %d\n\n",IsStackEmpty(headPtr)); //Everytime it is giving 1
Newnode->NextItemPtr=IsStackEmpty(headPtr)?NULL:headPtr;
headPtr=Newnode;
}
int main()
{
Stack* stackptr;
stackptr=(Stack*)malloc(sizeof(Stack));
stackptr->TOP=NULL;
pushItem(stackptr->TOP,3);
pushItem(stackptr->TOP,6);
return 0;
}
This statement does nothing for the caller:
headPtr=Newnode;
You can:
Pass a double pointer and assign to *headPtr
Return Newnode instead of assigning to headPtr
This C FAQ explains this very subject.
headPtr = Newnode;
Since headPtr is an argument of the function, it's passed by value. Modifying it inside the function does not have any effect in the caller. You need to pass a pointer to it and modify it through the pointer:
void pushItem(StackItem **headPtr, int n)
*headPtr = NewNode;
Related
I am trying to implement nodelist in c:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int value;
void *next;
} node_t;
void printlist(node_t*head){
for(node_t*i=head;i;i=i->next)
printf("%i\n",i->value);
}
node_t create(int value){
node_t *ret = malloc(sizeof(node_t));
ret->value=value;
ret->next=0;
return *ret;
}
int main(){
int i=0;
node_t*head=0;
for(node_t*tmp;i++<10;head=tmp)
{
*tmp=create(i+100);
tmp->next=head;
}
printlist(head);
}
and in the for loop, I am using node_t* pointer which is assign to already initialized (via malloc) struct outside in create function. But the program emits:
warning: ‘tmp’ may be used uninitialized in this function [-Wmaybe-uninitialized]
*tmp=create(i+100);
Command terminated
So how to assign a dereferenced pointer to already initialized data in c?
When you first enter the loop, tmp doesn't point to anything. Because of that, it's invalid to dereference the pointer.
Also, you have a memory leak in create. You dynamically allocate memory for a node but then return a copy of that node, leaving nothing to point to the allocated memory.
You can fix these issues by returning a pointer from the function:
node_t *create(int value){
node_t *ret = malloc(sizeof(node_t));
ret->value=value;
ret->next=0;
return ret;
}
And subsequently saving that pointer in tmp in the calling function:
tmp=create(i+100);
For starters the function create should return pointer to the created dynamically node. Otherwise you will be unable to free allocated nodes because the function returns a copy of a created node.
So rewrite the function at least like
node_t * create(int value){
node_t *ret = malloc(sizeof(node_t));
ret->value=value;
ret->next=0;
return ret;
}
In the for loop in main you are using an uninitialized pointer tmp. So with the function implementation of create as you defined it the loop invokes undefined behavior due to the underlined assignment
for(node_t*tmp;i++<10;head=tmp)
{
*tmp=create(i+100);
^^^^^^^^^^^^^^^^^^
tmp->next=head;
}
So after changing the function create change the loop like
for(node_t*tmp;i++<10;head=tmp)
{
tmp=create(i+100);
tmp->next=head;
}
Here is your updated program.
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int value;
void *next;
} node_t;
void printlist(node_t*head){
for(node_t*i=head;i;i=i->next)
printf("%i\n",i->value);
}
node_t * create(int value){
node_t *ret = malloc(sizeof(node_t));
ret->value=value;
ret->next=0;
return ret;
}
int main(){
int i=0;
node_t*head=0;
for(node_t*tmp;i++<10;head=tmp)
{
tmp=create(i+100);
tmp->next=head;
}
printlist(head);
}
Its output is
110
109
108
107
106
105
104
103
102
101
I'm trying to implement a linked list traversal, however my code is not working and I don't udnerstand why I've reassigned my pointer but it doesn't stick?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void inserter(Node *n1, int num){
if(n1==NULL){
Node *temp =(Node*)malloc(sizeof(Node));
temp->data=num;
temp->next=NULL;
n1=temp;
}
else{
Node *trav=n1;
while(trav!=NULL){
trav=trav->next;
}
}
}
int main(int argc, char **argv)
{
Node *l1 = NULL;
inserter(l1,l2,5);
inserter(l1,l2,11);
//It goes back into the NULL bracket despite me assigning it a node?
}
Here is the accompanying struct
typedef anode {
struct Node *next;
int data;
}Node;
Thank you for any help!I'm still new to all of this.
You're passing inserter() a pointer and an int. If you modify that int, no modifications would be visible from the calling function (I think you know that already). Same goes for the pointer: Node * is just a numeric type that holds an address, which has been passed by value.
If you want to modify where n1 points to, you'd need to dereference it. But because you don't want to change the contents of the memory that n1 points to, but change the value of n1 itself, your function would need to be passed a Node **.
Here's a quick example:
void inserter(Node **n, int num) {
if (*n == NULL) {
*n = malloc(...);
....;
}
....
}
That way you would change the actual value of n globally instead of just locally.
I want to pass a node by reference to a function and expect the variable in main() to be updated by the function
struct stack
{
int item;
struct stack *link;
};
void push(int item, struct stack *top)
{
/* allocate memory and insert item*/
}
int main(void)
{
struct stack *top;
push(10,top);
printf("%d\n",top->item);
return 0;
}
Here it displays 'segmentation fault', as if top did not get updated at all!
You need to pass the pointer top in main() by reference to the function push(). So give the address of top not its value.
So use
push(10,&top);
instead of
push(10,top);
if the changes made to top in push() are to reflected back in main().
This necessitates the modification of the function prototype. Use
void push(int item,struct stack **top)
instead of
void push(int item,struct stack *top)
And use *top in places where you used top in the push().
There are two options for what you need to do, depending on whether your function allocates the stack or the main() function allocates the stack element.
Option 1 — main() allocates top
void push(int item, struct stack *top)
{
top->link = 0;
top->item = item;
}
int main(void)
{
struct stack top; // Plain structure, not a pointer
push(10, &top); // Pass address of structure to function
printf("%d\n", top.item);
return 0;
}
This doesn't work particularly well in the context of a stack, but can often be the correct way to process structures — the calling code allocates the structure and the called code uses the allocated structure. Here is a dynamic allocation in the calling code, passed to the function to be initialized:
int main(void)
{
struct stack *top = malloc(sizeof(*top));
if (top != 0)
{
push(10, top);
printf("%d\n", top->item);
free(top);
}
return 0;
}
Option 2 — push() allocates top
void push(int item, struct stack **top)
{
struct stack *node = malloc(sizeof(*node));
node->link = *top;
node->item = item;
*top = node;
}
int main(void)
{
struct stack *top = 0; // Initialization is crucial
push(10, &top);
printf("%d\n", top->item);
push(20, &top);
printf("%d %d\n", top->item, top->link->item);
free(top->link);
free(top);
return 0;
}
This code is weird because it uses fixed operations instead of loops, but is otherwise kosher. All the code shown using malloc() has been tested with Valgrind and gets a clean bill of health.
I am creating a code to insert the elements in tree, but tinsert function does not insert; what is wrong with my code? I have checked many times but tree is always NULL.
The code has only 2 functions: one to insert, and second to show it in preorder.
#include<stdio.h>
#include<stdlib.h>
struct btree {
int val;
struct btree *left;
struct btree *right;
};
static int c=0;
typedef struct btree node;
void tinsert( node *n,int a)
{
c++;
printf("%d\n",c);
if(n==NULL)
{
n=(node *)malloc(sizeof(node));
n->left=NULL;
n->right=NULL;
n->val=a;
//printf("adding root %d\n",n->val);
//n=temp;
}
else if(a>=(n->val))
tinsert(n->right,a);
else
tinsert(n->left,a);
return ;
}
void preorder_display(node *n)
{
if(n!=NULL)
{
printf("%d\n",n->val);
preorder_display(n->left);
preorder_display(n->right);
}
else
printf("tree is null\n");
}
int main()
{
//int N;
//int num[100];
//int i;
node *ntree=NULL;
tinsert(ntree,4);
tinsert(ntree,6);
tinsert(ntree,8);
tinsert(ntree,1);
printf("tree is \n");
preorder_display(ntree);
return 0;
}
tinsert works on a local copy of your ntree, it doesn't change the one in your main. You can fix it by passing a pointer to it (i.e.: double pointer, pointer to a pointer).
So your tinsert will look like this:
void tinsert( node **n,int a)
And in your main you'll call it like this:
tinsert(&ntree,4);
Of course, you'll need to adjust the code in tinsert to de-reference the pointer and access it correctly.
Or allocate the root node in your main.
you pass your root node ntree to tinsert function by value, so when when the function is done you will stay with original value of ntree which is NULL.
You better rewrite your function, so you will pass pointer to pointer
void tinsert( node **n,int a)
//and invocation is like that :
tinsert(&ntree,4);
when you pass ntree from main to tinsert function,
new copy is created to your node*n;
One way is to make use of pointer to pointer
Or second solution is here:
Here is a solution:
#include<stdio.h>
#include<stdlib.h>
struct btree{
int val;
struct btree *left;
struct btree *right;
};
static int c=0;
typedef struct btree node;
node* tinsert( node *n,int a)
{
c++;
printf("%d\n",c);
if(n==NULL)
{
n=(node *)malloc(sizeof(node));
n->left=NULL;
n->right=NULL;
n->val=a;
//printf("adding root %d\n",n->val);
//n=temp;
}
else if(a>=(n->val))
tinsert(n->right,a);
else
tinsert(n->left,a);
return n;
}
void preorder_display(node *n)
{
if(n!=NULL)
{
printf("%d\n",n->val);
preorder_display(n->left);
preorder_display(n->right);
}
else
printf("tree is null\n");
}
int main()
{
//int N;
//int num[100];
//int i;
node *ntree=NULL;
ntree=tinsert(ntree,4);
ntree=tinsert(ntree,6);
ntree=tinsert(ntree,8);
ntree=tinsert(ntree,1);
printf("tree is \n");
preorder_display(ntree);
return 0;
}
C supports the pass by value only. However, this does not prevent you from modifying the value of a variable from another function, because you can always refer to a variable using it's memory; and in C it's done through pointers, an abstraction representing a memory location.
When you pass a value to the function, the value of the actual parameter is copied to the value of formal parameter. Note that a pointer's value is the address it points to. So, this value is copied into the formal parameter. So the new pointer inside the function points to the exact same location your original variable. You can deference the pointer anytime to manipulate it's value.
Here, you are required to manipulate a pointer. So you pass a pointer-to-pointer to the function:
tinsert(&ntree,4);
In your function, you deference it to get your original pointer; like the following:
void tinsert(node **n, int a)
{
//...
*n = malloc(sizeof(node));
//...
}
I am new to C. I have implemented a simple stack with some structs and what not. I have posted the entire code below. The problem section is commented.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
typedef struct Node{
int data;
struct Node *next;
} Node;
typedef struct Stack{
Node *top;
int size;
} Stack;
/* Function Prototypes */
void push(Stack *sPtr, int data);
int pop(Stack *sPtr);
void create(Stack *sPtr);
int main(void)
{
static Stack first;
create(&first);
push(&first,4);
push(&first,3);
push(&first,2);
printf("%d\n",pop(&first));
printf("%d\n",pop(&first));
printf("%d\n",pop(&first));
exit(1);
}
void push(Stack *sPtr, int data)
{
struct Node newNode;
newNode.data = data;
newNode.next = sPtr->top;
sPtr->top = &newNode;
sPtr->size++;
printf("%d\n",sPtr->top->data);
}
int pop(Stack *sPtr)
{
struct Node *returnNode = sPtr->top;
struct Node *topNode = sPtr->top;
if(sPtr->size != 0){
sPtr->top = topNode->next; /* =============PROBLEM?=============== */
return returnNode->data;
}
else{
printf("Error: Stack is Empty!\n");
return -1;
}
}
void create(Stack *sPtr)
{
sPtr->size = 0;
sPtr->top = NULL;
}
The output of this code is
4
3
2
2
8103136
680997
So obviously, it is pulling off the top node, and then printing the addresses of the next two nodes, instead of their data.
But why is it doing this? As far as I know (which is little) preforming this operation
sPtr->top = topNode->next;
should tell the program to make top now point to to topNode.next. But instead, it seems to be returning the address. What's going on here?
In your push() function, you're creating a new struct Node and adding it to your stack. However, the node is a local variable within the scope of push()--allocated on the stack (not your stack, the call stack), and will be gone when push() returns.
What you want to do is create the node on the heap, which means it will still be there after push() returns.
Since you're coding in C, you'll want to do something like:
struct Node *newNode = (struct Node*)malloc(sizeof(struct Node));
Since you're now dealing with heap-allocated memory, you'll need to make sure that at some point it gets freed (somewhere) using free().
You're also not decrementing size as Jonathan has pointed out.
One trouble is that pop() never decrements size, so size is really 'number of elements ever pushed onto stack', not 'the number of elements in the current stack'.
int pop(Stack *sPtr)
{
struct Node *returnNode = sPtr->top;
struct Node *topNode = sPtr->top;
if (sPtr->size != 0)
{
sPtr->top = topNode->next;
sPtr->size--;
return returnNode->data;
}
else
{
fprintf(stderr, "Error: Stack is Empty!\n");
return -1;
}
}
Another trouble, as pointed out by unluddite in his answer is that you are not pushing data correctly. You need both fixes to be safe. There might still be other problems (such as not freeing memory correctly — or at all), but these two will get you a long way.