Hello everyone I have this problem with my C code.
I'm implementing a stack and whenever I do pop it changes the stack in the function pop, but not the original stack .
please help.
here is my code
char pop(Node* top)
{
char result ;
if (size == 0) // The stack is empty.
{
return '\0' ;
}
else //The stack contains at least one element .
{
result = top->opp ;
top = top->next ;
}
size-- ;
return result;
}
We need more code but I will try:
I guess you use this function like this:
char pop(Node* top)
{
char result ;
if (size == 0) // The stack is empty.
{
return '\0' ;
}
else //The stack contains at least one element .
{
result = top->opp ;
top = top->next ;
}
size-- ;
return result;
}
int main()
{
// this is the top of the stack
Node *stack; // let's say there already are some elements in this stack
pop(stack);
return 0;
}
The problem is that you want to change the pointer value, then stack will point to the top of the stack. In order to do that, you have to use a pointer to a pointer, like this:
char pop(Node** top)
{
char result ;
Node *ptr;
ptr = *top;
if (size == 0) // The stack is empty.
{
return '\0' ;
}
else //The stack contains at least one element .
{
result = (*top)->opp ;
(*top) = (*top)->next ;
// You should free the pointer, like user2320537 said in his answer.
free(ptr);
}
size-- ;
return result;
}
int main()
{
// this is the top of the stack
Node *stack; // let's say there already are some elements in this stack
pop(&stack); // You give the pointer address
return 0;
}
Try char pop(Node** top) and operate on (*top)
You need to free the current position of top also... use free as
Node *ptr;
ptr = top;
if (size == 0) // The stack is empty.
{
return '\0' ;
}
else //The stack contains at least one element .
{
result = top->opp ;
top = top->next ;
}
free(ptr);
=================================================================
call it as
int main(){
Node front = NULL:
// place your code of PUSH here.
pop(&front); // will call the function **pop**
}
}
if you change the value of a variable you pass a pointer ( its address) to a function
eg
void increment(int *p) {
p += 1;
}
similarly to change the value of a POINTER you need to pass a pointer to the pointer to the function
char pop(Node **top) {
char t;
Node *p;
if( size == 0 ) {
return '\0';
} else {
p = *top;
t = p->op;
(*top) = (*top)-> next;
free(p);
return t;
}
}
Please send reference of top pointer to pop function like as "char pop(Node **top) { }" and add change your else block "top[0] = top[0]->next;" instead of "top = top->next ;".
Related
my code is not working but when I change struct stack *sp; to struct stack * sp = (struct stack *) malloc(sizeof(struct stack)); it start working. I am confused in when to allocate memory in heap to struct stack *ptr and when to not. It will be better if u can give me an example when struct stack *ptr can be used and when to use struct stack * sp = (struct stack *) malloc(sizeof(struct stack));
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stack
{
int size;
int top;
char *arr;
};
int stackTop(struct stack* sp){
return sp->arr[sp->top];
}
int isEmpty(struct stack *ptr)
{
if (ptr->top == -1)
{
return 1;
}
else
{
return 0;
}
}
int isFull(struct stack *ptr)
{
if (ptr->top == ptr->size - 1)
{
return 1;
}
else
{
return 0;
}
}
void push(struct stack* ptr, char val){
if(isFull(ptr)){
printf("Stack Overflow! Cannot push %d to the stack\n", val);
}
else{
ptr->top++;
ptr->arr[ptr->top] = val;
}
}
char pop(struct stack* ptr){
if(isEmpty(ptr)){
printf("Stack Underflow! Cannot pop from the stack\n");
return -1;
}
else{
char val = ptr->arr[ptr->top];
ptr->top--;
return val;
}
}
int precedence(char ch){
if(ch == '*' || ch=='/')
return 3;
else if(ch == '+' || ch=='-')
return 2;
else
return 0;
}
int isOperator(char ch){
if(ch=='+' || ch=='-' ||ch=='*' || ch=='/')
return 1;
else
return 0;
}
char* infixToPostfix(char* infix){
struct stack *sp;
sp->size = 10;
sp->top = -1;
sp->arr = (char *) malloc(sp->size * sizeof(char));
char * postfix = (char *) malloc((strlen(infix)+1) * sizeof(char));
int i=0; // Track infix traversal
int j = 0; // Track postfix addition
while (infix[i]!='\0')
{
if(!isOperator(infix[i])){
postfix[j] = infix[i];
j++;
i++;
}
else{
if(precedence(infix[i])> precedence(stackTop(sp))){
push(sp, infix[i]);
i++;
}
else{
postfix[j] = pop(sp);
j++;
}
}
}
while (!isEmpty(sp))
{
postfix[j] = pop(sp);
j++;
}
postfix[j] = '\0';
return postfix;
}
int main()
{
char * infix = "x-y/z-k*d";
printf("postfix is %s", infixToPostfix(infix));
return 0;
}
Two things to always remember when working with pointers in C:
Memory allocation is your problem. You have to think about the allocation of the memory which a pointer variable points to.
You have to be clear in your mind about the distinction between the pointer versus the data that it points to.
So when you say
struct stack *sp;
that will never work, all by itself. It won't work for a program that's implementing a stack, and it won't work for a program that's implementing any other kind of data structure.
When you write
struct stack *sp;
there is one important thing that you have done, and there is one important thing that you have not done.
The compiler allocates space to store one pointer. This pointer is known as sp. But:
The value of this pointer is indeterminate, which means that it does not point anywhere yet. You can't actually use the pointer variable sp for anything. (Yet.)
Or, in other words, going back to the distinction I mentioned earlier, you have taken care of the pointer but you don't have any data that the pointer points to.
But when you say
sp = malloc(sizeof(struct stack));
(and assuming malloc succeeds), now sp points somewhere: it points to a chunk of properly-allocated memory sufficient to hold one struct stack.
Sorry if my code and also English are a bit sketchy.
I am currently trying to print and deallocate the space in which my stack structs were stored with a function which the prototype is void printStack(struct cell *p). It calls also another function which is basically a pop function for stacks (once picked the first element stored in it, the function returns it) (struct cell *pop(struct cell **p)).
The body of both functions are here down below:
struct cell *pop(struct cell **p) {
struct cell *temp;
if(*p == NULL)
return *p;
else {
temp = *p;
*p = (*p)->next;
temp->next = NULL;
return temp;
}
}
void printStack(struct cell *p){
struct cell *popped;
if(p == NULL) {
printf("The stack is empty\n");
} else {
while(p != NULL) {
popped = pop(&p);
if(popped != NULL) {
printf("Value popped: %d\n", popped->elem);
free(popped);
}
}
}
}
The struct I have implemented is this one:
struct cell {
int elem;
struct cell *next;
};
The problem, now, is that the function clears everything except for the last element which keeps stored into the heap.
What have I done that brings to this behaviour?
You have to pass the pointer to the top node by reference.
void printStack( struct cell **p){
struct cell *popped;
if ( *p == NULL ) {
printf("The stack is empty\n");
} else {
while ( *p != NULL ) {
popped = pop( p );
if(popped != NULL) {
printf("Value popped: %d\n", popped->elem);
free(popped);
}
}
}
}
And if the pointer to the top node has for example the name p then the function is called like
printStack( &p );
Otherwise the original pointer passed as an argument will not be changed because the function deals with a copy of its value.
So the effect of passing by value is that the data member next of the original pointer to the top node will be set to NULL due to this statement
temp->next = NULL;
within the function pop while the original pointer itself will store the same value that it had before calling the function printStack.
Take into account that you could rewrite the while loop within the function the following way
while ( ( popped = pop( p ) ) != NULL ) {
printf("Value popped: %d\n", popped->elem);
free(popped);
}
This question already has answers here:
How to change value of variable passed as argument?
(4 answers)
Closed 5 years ago.
The program has no problem in the push function as I can reach the members of the structure (e.g. key). If I call push(stack, 3) the key is 3 within the push function on the newElem pointer that has been allocated on the HEAP, but then when it is assigned to the stack, and used outside of push function (used in main), it no longer has a clue what values the members of the struct has at that current address. So it seems to me that the malloc doesn't really work and doesn't put the memory on the HEAP since It's not accessible anymore through the main function??
#include <stdio.h>
#include <stdlib.h>
typedef struct list_element_t {
int key;
struct list_element_t* next;
struct list_element_t* prev;
}ListElement;
ListElement* GetNewElement(int k) {
ListElement* newElem = (ListElement*) malloc(sizeof(ListElement));
newElem->key = k;
newElem->next = NULL;
newElem->prev = NULL;
return newElem;
}
void push(ListElement* S, int k) {
ListElement* newElem = GetNewElement(k);
//The key is always correct here
printf("%d\n", newElem->key);
if(S == NULL) {
S = newElem;
//S is not NULL here.
return;
}
newElem->next = S;
S->prev = newElem;
//Put our stack in the back of the list
S = newElem;
}
void display(ListElement* S) {
ListElement* temp = S;
while(temp != NULL) {
printf("%d\n", temp->key);
temp = temp->next;
}
}
int main(int argc, char **argv)
{
ListElement* stack = NULL;
push(stack, 3);
//stack is still NULL here????
//Causes segmentation Fault
printf("%d\n", stack->key);
//Never prints anything (stack is NULL)
display(stack);
return 0;
}
S in push function is local variable, so in this assigment
S = newElem;
you assign newElem to temporary object which is destroyed when push ends. If you want to modify content pointed by S you should pass this by pointer to pointer.
void push(ListElement** S, int k) {
ListElement* newElem = GetNewElement(k);
printf("%d\n", newElem->key);
if(*S == NULL) {
*S = newElem;
return;
}
newElem->next = *S;
(*S)->prev = newElem;
*S = newElem;
}
and in main function call push function as follows
ListElement* stack = NULL;
push(&stack, 3);
typedef struct student *std_ptr;
struct student
{
int number;
std_ptr next;
};
typedef std_ptr STACK;
create_stack(void)
{
STACK S;
S = (STACK) malloc( sizeof( struct student ) );
if(S == NULL) printf("out of space!");
return S;
}
void push(int x, STACK S)
{
std_ptr tmp;
tmp = (std_ptr) malloc(sizeof(struct student));
if(tmp == NULL) printf("out of space!");
else
{
tmp -> number = x;
tmp -> next = S -> next;
S -> next = tmp;
}
}
int main()
{
push(12058010,STACK S);
return 0;
}
Im trying to call function and I get error: expected expression before stack.I also tried to call the function like that
int main()
{
push(12058010,S);
return 0;
}
This time I get error: 'S' undeclared(first use in this function)
Thank you for your help!
Define the variable s by doing:
STACK s;
Initialise it:
s = create_stack();
Test whether the initialisation succeeded:
if (NULL == s)
{
return EXIT_FAILURE;
}
Use it by calling push() like this:
push(12058010, s);
All together this could look like this:
int main(void)
{
STACK s = create_stack(); /* This merges step 1 and 2. */
if (NULL == s)
{
return EXIT_FAILURE;
}
push(12058010, s);
return EXIT_SUCCES;
}
S is neither in the global scope nor in the scope of main().
I suspect you meant to write STACK S = create_stack(); as the first statement in main().
Don't forget to free the allocated memory as well.
A language has not array as a data type but it has stack as a data type and one can declare stack's; and push, pop and isempty operations are defined.
So how can we implement array using two stacks and above operations?
Horribly inefficient - but:
Stack 1 Contains the details
Stack 2 is empty.
To go through the array, Pop Stack 1 , when you want the next one, push the previous one into stack 2 and pop stack 1 again. Repeat until 'isempty'.
If you want the Nth value, pop the not empty stack N times while pushing the unneeded ones into the other stack. Then when you're done playing with it, empty it into the other stack. Note that this;ll flip the order.
With two stacks you can get some sort of random access (which is what you're interested in an array) like this:
Put everything on a stack.
Every time you have to access something that's not the top of the stack (pop), you pop all elements from this stack and push them in order to the second one.
By passing elements from one stack to another you simulate iteration.
First element of array is a bottom of stack1;
Last element of array is a bottom of stack2;
Current element of array is a top of stack1;
Iterates through the array by shifting the elements of the stack1 to stack2(move to the begin) and vice versa (move to end).
#include <stdio.h>
#include <stdlib.h>
#define Type int
#define DefaultValue 0
#define bool int
typedef struct stack{
Type *stack;
Type *sp;
size_t size;
} Stack;
Stack* Stack_make(size_t size){
Stack *s;
s = (Stack*)malloc(sizeof(Stack));
s->stack = (Type*)malloc(sizeof(Type)*size);
s->sp = s->stack -1;
s->size = size;
return s;
}
bool Stack_empty(Stack *s){//isempty
return s->sp < s->stack;
}
void Stack_push(Stack *s, Type value){
if(s->sp >= s->stack + s->size -1){
fprintf(stderr, "stack over flow\n");
exit(-1);
}
*(++s->sp) = value;
}
Type Stack_pop(Stack *s){
if(Stack_empty(s)){
fprintf(stderr, "stack is empty\n");
exit(-2);
}
return *s->sp--;
}
void Stack_free(Stack *s){
if(s!=NULL){
free(s->stack);
free(s);
}
}
typedef struct array {
Stack *front;
Stack *back;
size_t size;
size_t index;
} Array;
Array* Array_make(size_t size){
Array *a;
int i;
a = (Array*)malloc(sizeof(Array));
a->front = Stack_make(size);
a->back = Stack_make(size);
a->size = size;
//initialize
Stack_push(a->front, DefaultValue);
for(i=0;i<size;++i){
Stack_push(a->back, DefaultValue);
}
a->index = 0;
return a;
}
void Array_pos_set(Array *a, size_t index){
if(index < 0 || index >= a->size){
fprintf(stderr, "out of range\n");
exit(-11);
}
if(a->index < index){
while(a->index < index){
Stack_push(a->front, Stack_pop(a->back));
++a->index;
}
} else if(a->index > index){
while(a->index > index){
Stack_push(a->back, Stack_pop(a->front));
--a->index;
}
}
}
Type Array_set(Array *a, size_t index, Type value){
Array_pos_set(a, index);//a->index == index
Stack_pop(a->front);
Stack_push(a->front, value);
return value;
}
Type Array_get(Array *a, size_t index){
Type value;
Array_pos_set(a, index);//a->index == index
value = Stack_pop(a->front);
Stack_push(a->front, value);
return value;
}
void Array_free(Array *a){
Stack_free(a->front);
Stack_free(a->back);
free(a);
}
int main(){
Array *a;
int i;
a = Array_make(10);
for(i=0;i<10;i++){
Array_set(a, i, i+1);//a[i] = i+1;
}
for(i=0;i<10;i++){
printf("%d\n", Array_get(a, i));// a[i];
}
Array_free(a);
return 0;
}