My problem is based on pointers, I want to know how can i pass top of stack in function printStack() so that i can access all nodes of stack.I am storing elements in array and same time pushing into stack.
here in this code when i execute it does not print anything.
here my code
#include<stdio.h>
struct stack
{
int data;
struct stack *next;
};
typedef struct stack s;
s *top=NULL,*neu;
//push data into stack
void push(int data)
{
neu = (s *)malloc(sizeof(s));
neu->data= data;
neu->next = NULL;
if(!top)
{
neu=top;
}
else
{
neu->next = top;
top = neu;
}
}
//pop data and move top to top->next
void pop()
{
s *temp = top;
top = top->next;
free(top);
}
//print data present in stack
void printStack(s *top)
{
while(top)
{
printf("%d ",top->data);
pop();
}
}
int main()
{
int i=0,A[3],d;
for(i=0;i<3;i++)
{
scanf("%d",&A[i]);
push(A[i]);
}
printStack(top);
return 0;
}
So there are 3 problems:-
You are freeing top rather than temp in pop().
You are changing to the local variable passed in printStack.
Simply call this printSack(); having function signature void printStack().
Also when creating the nodes
if(!top)
{
neu=top;
^^^^
}
This will be top=neu;
Some things that you should learn to do:-
Use debugger. Learn how to use it.
Don't cast the return value of malloc.
Check the return value of malloc and scanf.
You have used too many global variables - code that involves lots of global variables are tend to be difficult to debug. You could easily avoid it here.
For example:-
if( scanf("%d",&A[i])!= 1){
fprintf(stderr,"Error in input");
exit(EXIT_FAILURE);
}
In case of malloc
neu = malloc(sizeof(s));
if(neu == NULL ){
perror("Malloc failed");
exit(EXIT_FAILURE);
}
The main thing is - your code is doing nothing basically. It is even useless to create those methods which are so closely couped with each other with data. We use functions so that code becomes modular and each of the function should be reusable.( Atleast to some extent). Here you have missed that part.
You have a simple error here:
void pop()
{
s *temp = top;
top = top->next;
free(top);
}
Rather than freeing Top, you likely meant to free(temp);
Additionally, consider developing good habits early. Don't cast the return of malloc() in C. Also, don't assume that malloc() worked; check to see if it returns something other than NULL.
Related
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.
Suppose I have some recursive function that manipulates a graph structure:
typedef struct Node {
Data data;
size_t visited;
size_t num_neighbors;
struct Node *neighbors[];
} Node;
void doSomethingWithNode(Node *node)
{
if ((!node) || node->visited)
return;
node->visited = 1;
/* Do something with node->data */
size_t /* some local variables */;
size_t i;
for (i = 0; i < node->num_neighbors; i++)
{
/* Do some calculations with the local variables */
if (/* something */)
doSomethingWithNode(node->neighbors[i]);
}
}
Because of the local variables I use in the loop, the compiler (gcc) creates a larger-than-I-would-like stack frame for this function (a good number of pushq and popq instructions even with -O3), which is a problem, since it is deeply recursive. Since it doesn't matter what order I visit the nodes in, I could refactor this code to use a stack of Node pointers, thus reducing the overhead to one pointer per iteration.
Are there any hints I can give the compiler (gcc) to fix this problem?
If not, is it possible to make use of the call stack itself for my stack of pointers without resorting to assembly?
You could maintain a vector or a list (or some queue, or perhaps a stack, or even some arbitrary unordered set) of nodes to be visited (and you probably want to maintain a set or hash table of already visited nodes).
Then you'll have a loop which picks the node in front of the to-be-visited container, and might add some unvisited nodes in the back of that container....
Read the wikipages about continuation passing style and about tail calls
Google also for Deutsch Schorr Waite Algorithm, it could give you some ideas.
Can you put the calculations into their own, non-recursive function? That way the stack for all the temporary variables will not be there when you make the recursive call.
Update: looks like at least some data in the local variables is essential for recursion. You can use alloca to explicitly allocate memory on the stack.
What would you expect the compiler to do in order to solve the problem?
You can of course go through your code, and minimize the number of local variables, try to make it as clear as possible that they are (for instance) only assigned to once by using const when possible, and so on. This might make the compiler re-use the space, if possible.
Failing that, you can probably save some memory by going iterative instead since that cuts out the need for the return address.
You can use malloc and realloc to manage a dynamically-growing stack of nodes. Here's a "class" for managing the stack:
typedef struct Stack {
void **pointers;
size_t count;
size_t alloc;
} Stack;
void Stack_new(Stack *stack)
{
stack->alloc = 10;
stack->count = 0;
stack->pointers = malloc(stack->alloc * sizeof(void*));
}
void Stack_free(Stack *stack)
{
free(stack->pointers);
stack->pointers = null;
}
void Stack_push(Stack *stack, void *value)
{
if (stack->alloc < stack->count + 1) {
stack->alloc *= 2;
stack->pointers = realloc(stack->pointers, stack->alloc * sizeof(void*));
}
stack->pointers[stack->count++] = value;
}
void *Stack_pop(Stack *stack)
{
if (stack->count > 0)
return stack->pointers[--stack->count];
return NULL;
}
"it is deeply recursive" is a hint that the deepest recursions occur in paths that do not have more than 1 non-visited neighbor.
Let code only recurse when there is more than 1 interesting neighbor, otherwise just loop.
void doSomethingWithNode(Node *node) {
while (node) {
if (node->visited) return;
node->visited = 1;
/* Do something with node->data */
size_t /* some local variables */;
size_t i;
Node *first = NULL;
for (i = 0; i < node->num_neighbors; i++) {
/* Do some calculations with the local variables */
if (/* something */) {
// Save the first interesting node->neighbors[i] for later
if (first == NULL &&
node->neighbors[i] != NULL &&
node->neighbors[i]->visited == 0) {
first = node->neighbors[i];
} else {
doSomethingWithNode(node->neighbors[i]);
}
}
}
node = first;
}
}
This does not reduce the stack frame, but eliminate recursion when there is only 1-ply. IOWs: when recursion is not needed.
The recursion depth should now no longer exceed O(log2(n)) instead of the original worst-case O(n)
If you have more number of local variables and arrays then you can try allocating memory using malloc,manipulate it using single pointer and fixed offsets .free the memory while exiting from function.
In this way you will save the stack and reuse same heap(maybe) section for all the iterations.
I find many if the other answers not elegant and requiring much overhead. Probably there is no good way and any way depends on the type of recursion at hand.
In your case, the recursion is at the end and only variable i is still needed. To reduce the stack frame, you can use for al other variables global space.
If you want to reduce even more and remove i, you can use node->visisted as a counter:
static struct VARS {
int iSomething;
Data *dataptr;
double avg;
} gVars;
void doSomethingWithNode(Node *node)
{
if ((!node) || node->visited)
return;
/* Do something with node->data */
/* some local variables in global space */;
gVars.iSomething= 1;
for (; node->visited < node->num_neighbors; node->visited++)
{
/* Do some calculations with the local variables */
if (/* something */)
doSomethingWithNode(node->neighbors[node->visited]);
}
}
Put all local variables which are not essential for recursion into struct locals and access them with plocals->. The advantage over putting the calculations into their own, non-recursive function (Arkadiy's answer) is, if needed, that the variables are valid and retain their values over the recursions.
#include <stddef.h>
struct Data {
char data[1];
};
typedef struct Node {
struct Data data;
size_t visited;
size_t num_neighbors;
struct Node *neighbors;
} Node;
struct Locals {
/* local variables not essential for recursion */;
};
static void doSomethingWithNodeRecurse(Node *node, struct Locals *plocals)
{
if ((!node) || node->visited)
return;
node->visited = 1;
/* Do something with node->data */
/* local variables essential for recursion */
size_t i;
for (i = 0; i < node->num_neighbors; i++)
{
/* Do some calculations with the local variables */
if (1/* something */)
doSomethingWithNodeRecurse(&node->neighbors[i], plocals);
/* Do some calculations with the local variables */
}
}
void doSomethingWithNode(Node *node)
{
struct Locals locals;
doSomethingWithNodeRecurse(node, &locals);
}
If the variables are still too huge to allocate them on the stack, they can be allocated on the heap as Vagish suggested:
#include <stddef.h>
#include <stdlib.h>
struct Data {
char data[1];
};
typedef struct Node {
struct Data data;
size_t visited;
size_t num_neighbors;
struct Node *neighbors;
} Node;
struct Locals {
/* local variables too big for allocation on stack */;
};
void doSomethingWithNode(Node *node)
{
struct Locals *plocals;
if ((!node) || node->visited)
return;
/* ---> allocate the variables on the heap <--- */
if ((plocals = malloc(sizeof *plocals)) == NULL) abort();
node->visited = 1;
/* Do something with node->data */
size_t i;
for (i = 0; i < node->num_neighbors; i++)
{
/* Do some calculations with the local variables */
if (1/* something */)
doSomethingWithNode(&node->neighbors[i]);
/* Do some calculations with the local variables */
}
/* ---> free the variables <--- */
free(plocals);
}
I have been doing excercises from a book. And I am stuck on the meaning of this qustion. Assuming that you store integer values on the stac and that using a static array to store data provide a createStack() deleteStack(stack) methods.
My interpretation is
typedef struct {
int values;
char data[50];
} StackData;
typedef struct n {
StackData d; // store some data in node
struct n *successor; // store successor of node
// as typedef is not yet completed
// name StackNode cannot be used
} SatckNode;
typedef struct {
StackNode *head;
StackNode *current;
} Stacklist;
I know these arent the methods. But i want to know if I am going about it the right way
If you're using a static array for the values, then you don't technically need createStack() and deleteStack() functions, because you can just create a struct stack or whatever on the stack (pun intended) and you're done.
If you do want to, though, (and you might legitimately want to, e.g. to avoid having to explicitly initialize top, or to hide the implementation behind an opaque type, or to be able to return one from a function without copying a potentially large array) this'll do it:
#include <stdio.h>
#include <stdlib.h>
#define STACKSIZE 50
typedef struct stack * Stack;
struct stack {
size_t top;
int values[STACKSIZE];
};
Stack createStack(void)
{
Stack new_stack = malloc(sizeof *new_stack);
if ( !new_stack ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
new_stack->top = 0;
return new_stack;
}
void deleteStack(Stack stack)
{
free(stack);
}
void push(Stack stack, const int n)
{
if ( stack->top < STACKSIZE ) {
stack->values[stack->top++] = n;
}
else {
fprintf(stderr, "Stack full - exiting.\n");
exit(EXIT_FAILURE);
}
}
int pop(Stack stack)
{
if ( stack->top > 0 ) {
return stack->values[--stack->top];
}
else {
fprintf(stderr, "Stack empty - exiting.\n");
exit(EXIT_FAILURE);
}
}
int main(void)
{
Stack mystack = createStack();
push(mystack, 3);
push(mystack, 1);
push(mystack, 4);
push(mystack, 1);
push(mystack, 5);
for ( size_t i = 0; i < 5; ++i ) {
printf("Popped %d from stack.\n", pop(mystack));
}
deleteStack(mystack);
return 0;
}
Right now you seem to want a stack with values in a static array, but then you start defining structs for nodes and lists, as if you want a linked list implementation. The two implementations are obviously pretty different.
I think you're on the right way - just a couple of comments.
In Stacklist, I don't get why you have pointers to two of the nodes in the stack.
Usually, stacks only keep a reference to the item on the top of the stack.
In addition, they either keep a counter of how big is the stack, or a pointer to the node on the bottom of the stack (which is what you probably mean by head, and reference the head node by current?).
And don't forget to initialize everything whenever you create any of those structures :P usually ends up in endless hours of headache.
Keep up the good work.
I am in an OS class and I have to write a simple stack program (the main function just determines what the user is asking you to do). If this were not required to be in C, I would have had this done ages ago, but because I am not very good at C coding, it has "a bug"... The bug so far is that it just continues to "pop" the same value off. (It's not actually popping anything off). I think it's because I don't understand how structures and pointers really work. Or is it a not so obvious coding mistake?
#include <stdio.h>
struct node {
int data;
struct node *next;
struct node *prev;
} first;
void push(int);
void pop();
int main(void)
{
int command = 0;
while (command != 3)
{
printf("Enter your choice:\n1) Push integer\n2) Pop Integer\n3) Quit.\n");
scanf("%d",&command);
if (command == 1)
{
// push
int num;
scanf("%d",&num);
push(num);
}
else
{
if (command == 2)
{
pop();
}
else
{
if (command != 3)
{
printf("Command not understood.\n");
}
}
}
}
return 0;
}
void push (int x)
{
struct node newNode;
newNode.data = x;
newNode.prev = NULL;
newNode.next = &first;
first = newNode;
printf("%d was pushed onto the stack.\n", first.data);
}
void pop()
{
if (first.data == '\0')
{
printf("Error: Stack Empty.\n");
return;
}
printf("%d was popped off the stack.\n", first.data);
first = *(first.next);
first.prev = NULL;
}
first should be a pointer. change it to struct node *first;
in main initialize first=NULL;
change you push/pop operations as below,
void push (int x)
{
struct node *newNode;// It should be a pointer
newNode = (struct node *)malloc(sizeof(struct node));
newNode->data = x;
//newNode.prev = NULL; // You don't need this
newNode->next = first;
first = newNode;
printf("%d was pushed onto the stack.\n", first->data);
}
void pop()
{
struct node *prevPtr;
//if (first.data == '\0')
if (first == NULL) // check if stack is empty
{
printf("Error: Stack Empty.\n");
return;
}
printf("%d was popped off the stack.\n", first->data);
prevPtr = first;
first = first->next;
free(prevPtr);
}
The problem is that first is a single global node, and it's the only node you ever have (aside from a temporary local node inside your call to push).
This line:
first = newNode;
just copies the contents of newNode over into first; and since newNode.next is pointing to first, this means that now first.next is pointing to first, so you have a single-element circular linked list.
Similarly, this line:
first = *(first.next);
just copies the contents of *(first.next) over into first; which is a no-op, since (due to the above), *(first.next) is first.
To solve this problem, you actually need to dynamically create nodes, using malloc (and free). And your global first variable should be a pointer — a node * — that always points to the top element of the stack. (Better yet, your push and pop functions should take first as an argument, rather than having this as a global variable. There's no need for these functions to only allow a single stack to exist.)
What's the value of &first? Hint, it's always the same since first is statically allocated. Even if you change the contents of the structure, the address won't change. This might tell you why there's a bug in push. You'll need to use malloc and free if you are going to have a structure of varying size.
When you have to manage memory yourself, as C requires you to do, you need to know the difference between areas of memory known as the stack and the heap. (This "stack" is slightly different than the data structure you are creating in your program.)
Your push() function is creating a new node on the stack; when the function exits the stack is popped and the memory occupied by your new node is up for grabs. The fact that you see values you entered is due to the fact that your program is very simple. If it was calling other functions that did other things they would almost certainly overwrite that part of the stack and when you called pop(), you would see garbage.
As others have indicated, you need to use the functions malloc() and free(), which give you memory from the heap instead of the stack.
If you want to make a stack with a linked list, make first variable as a pointer. then, when you push a new node to the stack, make a new node by allocating on the heap memory by malloc(). I know that you intend to use it to point to the top of the stack. right?
In your code, first variable is overwritten by a new node since it is not a pointer variable but a value variable. That makes a result to lost a top node of the stack.
void pop()
{
struct node *prevPtr;
//if (first.data == '\0')
if (first == NULL)
{
printf("Error: Stack Empty.\n");
return;
}
printf("%d was popped off the stack.\n", first->data);
prevPtr = first;
first = first->next;
free(prevPtr);
}
#include<stdio.h>
# define max 10
int stack[max],top=-1,size=0;
void push()
{
if(top==(max-1))
{
printf("stack full\n");
}
else
{
top++;
printf("enter the value which you want to insert\n");
scanf("%d",&stack[top]);
}
}
void pop()
{
int str;
if(top==-1)
{
printf("stack empty\n");
}
else
{
str=stack[top];
top--;
printf("the removed element is %d\n",str);
}
}
void display()
{
int i;
for(i=0;i<top;i++)
{
printf("%d\n",stack[i]);
}
}
void main()
{
int enter,x;
do
{
printf("enter 1 for push the element in the array\n");
printf("enter 2 for pop the element in the array\n");
printf("enter 3 for display the element in the array\n");
scanf("%d",&enter);
switch(enter)
{
case 1:push();
break;
case 2:pop();
break;
case 3:display();
break;
default:
printf("invalid syntax");
}
printf("for continue press 0\n");
scanf("%d",&x);
}
while(x==0);
}
when I'm trying to push elements to a stack I get segmentation fault, but if I open address for stack(i marked them with "!!!") and it's symbols it accepts it. But this time in each push, it creates new address and doesn't increase top value.
typedef struct
{
struct table **symbols; // array of the stack
int top; //index of the top element
int size; //maximum size of the stack
}stack;
void push(stack *stck,struct table *element)
{
if(stck->top == stck->size)
{
printf("stack is full");
return;
}
stck = malloc(sizeof(stack)); !!!
stck->symbols = (struct table **)malloc(50 * sizeof(struct table*)); !!!
printf("top : %d\n",stck->top);
stck->top = stck->top++;
printf("%d"&stck->top);
stck->symbols[stck->top] = element;
printf("top : %d\n",stck->top);
}
You have to construct your stack before you can push anything onto it. Eg. create function stack_new that will allocate memory for your stack and initialize its members:
stack * stack_new (size_t size)
{
stack * stck = malloc(sizeof(stack));
stck->top = -1;
stck->size = size
stck->symbols = (struct table **)malloc(size * sizeof(struct table*));
return stck;
}
Now, once you properly constructed your stack with above function, you may pass it to push function.
You are passing one stack in a variable called stck, but then allocating a new structure and assigning it to the same pointer. So the stack you pass in is never modified. I don't think you need the first malloc call.
Before you ever call push, you are going to want to malloc space for the stack.
With the !!! lines, you are allocating new memory with each push, which is wrong.
Without the !!! lines, you are never allocating the memory
If you pass a single pointer stack *stck and then malloc inside the function, it will not reflect once you get out the function.
Also, why do you need to allocate memory for table for 50 pointers each time you want to push?
Do it like below:
struct table
{
//members go here
};
typedef struct
{
struct table **symbols;
int top;
int size;
}stack;
struct table *get_elem(void)
{
//logic for getting elements go here
}
void stack_push(stack *stck, struct table *element)
{
if(stck->top==stck->size)
{
printf("Stack Full\n");
return;
}
stck->top++;
stck->symbols[stck->top] = element;
return;
}
void stack_func()
{
struct table *elem = NULL;
stack *stck = (stack *)malloc(sizeof(stack));
if(NULL==stck)
{
return;
}
stck->top = -1;
stck->symbols = (struct table **)malloc(50 * sizeof(struct table *));
if(NULL == stck->symbols)
{
free(stck);
return;
}
stck->size = 49;
elem = get_elem();
//do check here for correctness of elem returned from get_elem
stack_push(stck, elem);
return;
}
Hope this helps! : )