I have a question about my piece of code here: I tried to write a function, its name is take, the function can get only one int parameter and have to return back the middle number that was inserted. The function has to use in, as minimum memory as possible. I tried to use in a stack. Its my implementation. The problem is that the program doesn't return a value after the third insertion.
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int take (int);
typedef struct stack
{
int num;
struct stack *next;
}stack;
stack first;
bool isit = true;
int counter = -1;
int main()
{
printf("%d",take(5));
printf("%d", take(6));
printf("%d", take(7));
return 0;
}
int take(int value)
{
if (isit)
{
isit = false;
first.num = value;
first.next = NULL;
}
else
{
static stack newone;
newone.num = value;
newone.next = NULL;
stack temp = first;
while (temp.next != NULL)
{
temp = *temp.next;
}
temp.next = &newone;
}
stack *temp1 = malloc(sizeof(stack));
*temp1 = first;
counter++;
if (counter > 1 && counter % 2 == 0)
{
temp1 = temp1->next;
}
return (temp1->num);
}
A big problem in your code is that you use global variables where you don't need
them. This creates problems that don't expect, like this:
int take(int value)
{
...
static stack newone;
newone.num = value;
newone.next = NULL;
stack temp = first;
while (temp.next != NULL)
{
temp = *temp.next;
}
temp.next = &newone;
The static stack newone is a static variable, it means it will be always the
same every time you call take, you are overwriting the values all the time,
specially the next pointer.
For this reason, avoid using global variables when you can perfectly declare
them in the main function and pass them to the other functions.
Also you malloc part doesn't make any sense. You want minimal memory footprint
but you allocate memory which is lost after temp1 = temp1->next;.
If you want a minimal memory footprint and not having to allocate memory with
malloc, then you can declare an array of fixed length and use it as a stack,
something like this:
typedef struct stack
{
int stack[20];
size_t len;
size_t size;
} Stack;
void stack_init(Stack *stack)
{
if(stack == NULL)
return;
stack->size = sizeof stack->stack / sizeof stack->stack[0];
stack->len = 0;
}
int stack_is_empty(Stack *stack)
{
if(stack == NULL)
return 1;
return stack->len == 0;
}
int stack_is_full(Stack *stack)
{
if(stack == NULL)
return 0;
return stack->len == stack->size;
}
int stack_push(Stack *stack, int value)
{
if(stack == NULL)
return 0;
if(stack_is_full(stack))
return 0;
stack->stack[stack->len++] = value;
return 1;
}
int stack_pop(Stack *stack, int *val)
{
if(stack == NULL)
return 0;
if(stack_is_empty(stack))
return 0;
stack->len--;
if(val)
*val = stack->stack[stack->len];
return 1;
}
int take(Stack *stack, int value)
{
if(stack == NULL)
return 0;
if(stack_push(stack, value) == 0)
fprintf(stderr, "stack is full, cannot push\n");
return stack->stack[stack->len / 2];
}
int main(void)
{
Stack stack;
stack_init(&stack);
printf("%d", take(5));
printf("%d", take(6));
printf("%d", take(7));
return 0;
}
Related
I made a stack and i am using the isEmpty function but the output is not coming. I trued manually using the gcc command and also using the code runner extension.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
typedef struct Stack
{
int top;
int size;
int *arr;
} Stack;
int isEmpty(Stack *st)
{
if (st->top == -1)
{
return 1;
}
else
{
return -1;
}
}
int main()
{
Stack *st;
st->top = -1;
st->size = 10;
st->arr = (int *)malloc(st->size * sizeof(int));
int i = isEmpty(st);
if (i == 1)
{
printf("The stack is empty\n");
}
else
{
printf("The stack is not empty\n");
}
return 0;
}
The file is named Stack.c.
There is one more thing that the basic hello world program is working perfectly
Stack *st;
st->top = -1;
You invoked undefined behavior by accessing uninitialized pointer st->top = -1;.
You should initialize st first:
Stack *st = malloc(sizeof(Stack));
Basically I made a create_app() function to allocate 2 nodes in the stack, each having a pointer to an array[max]; undo() pops the last element, and before returning it, it adds it into the REDO node's array. redo() does the opposite, pops the last element in it's array, putting it into Undo's array before returning it. What did I do wrong ?
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define EMPTY_TOS (-1)
typedef struct node *node_ptr;
struct node
{
int arr_size;
int tos;
int *arr_stack;
node_ptr next;
};
typedef node_ptr STACK;
STACK
create_app(int max)
{
STACK UNDO = (STACK) malloc(sizeof(struct node));
STACK REDO = (STACK) malloc(sizeof(struct node));
{
UNDO->arr_stack == (int *) malloc(max * sizeof(int));
REDO->arr_stack == (int *) malloc(max * sizeof(int));
if(UNDO->arr_stack != NULL){printf("Out of space!");}
else
{
UNDO->tos = EMPTY_TOS;
REDO->tos = EMPTY_TOS;
UNDO->arr_size = max;
REDO->arr_size = max;
UNDO->next = REDO;
REDO->next = UNDO;
return UNDO;
}
}
}
int
isEmpty(STACK S)
{
return(S->tos==-1);
}
int
isFull(STACK S)
{
return(S->tos>=S->arr_size-1);
}
void
push(int x, STACK S)
{
if(isFull(S)){printf("Stack full!");}
else
{
S->arr_stack[++S->tos] = x;
}
}
int
undo(STACK S)
{
if(isEmpty(S)){printf("Nothing to undo!");}
else
{
S->next->arr_stack[++S->next->tos] = S->arr_stack[S->tos];
printf("%d",S->arr_stack[S->tos--]);
}
}
int
redo(STACK S)
{
if(isEmpty(S->next)){printf("Nothing to redo!");}
else
{
int temp = S->next->arr_stack[S->next->tos];
push(S->next->arr_stack[S->next->tos], S);
S->next->tos--;
printf("%d",temp);
}
}
int main()
{
STACK app = create_app(5);
push(1,app);
push(2,app);
push(3,app);
undo(app);
undo(app);
redo(app);
redo(app);
/* Expected output: 3223 */
return 0;
}
Some small errors were in your code, like these ones in create_app() which seem like typos.
UNDO->arr_stack == (int *) malloc(max * sizeof(int));
REDO->arr_stack == (int *) malloc(max * sizeof(int));
^
|
if(UNDO->arr_stack != NULL){printf("Out of space!");}
^
|
...
and some int returning functions did not return anything in the else part which gave some warnings.
Here is the modified code, which worked fine for me
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define EMPTY_TOS (-1)
typedef struct node* node_ptr;
struct node
{
int arr_size;
int tos;
int *arr_stack;
node_ptr next;
};
typedef node_ptr STACK;
STACK
create_app(int max)
{
STACK UNDO = (STACK) malloc(sizeof(struct node));
STACK REDO = (STACK) malloc(sizeof(struct node));
{
UNDO->arr_stack = (int *) malloc(max * sizeof(int));
REDO->arr_stack = (int *) malloc(max * sizeof(int));
if(UNDO->arr_stack == NULL){printf("Out of space!");
return NULL;}
else
{
UNDO->tos = EMPTY_TOS;
REDO->tos = EMPTY_TOS;
UNDO->arr_size = max;
REDO->arr_size = max;
UNDO->next = REDO;
REDO->next = UNDO;
return UNDO;
}
}
}
int
isEmpty(STACK S)
{
return (S->tos == -1);
}
int
isFull(STACK S)
{
return (S->tos >= S->arr_size-1);
}
void
push(int x, STACK S)
{
if(isFull(S)){printf("Stack full!");}
else
{
S->arr_stack[++S->tos] = x;
}
}
void
undo(STACK S)
{
if(isEmpty(S)){printf("Nothing to undo!");}
else
{
S->next->arr_stack[++S->next->tos] = S->arr_stack[S->tos];
printf("%d",S->arr_stack[S->tos--]);
}
}
void
redo(STACK S)
{
if(isEmpty(S->next)){printf("Nothing to redo!");}
else
{
int temp = S->next->arr_stack[S->next->tos];
push(S->next->arr_stack[S->next->tos], S);
S->next->tos--;
printf("%d",temp);
}
}
int main()
{
STACK app = create_app(5);
push(1,app);
push(2,app);
push(3,app);
undo(app);
undo(app);
redo(app);
redo(app);
/* Expected output: 3223 */
return 0;
}
Result:
3223
However, always take precaution in deallocating the memory malloced using free().
I am practicing the Leetcode question "Next Greater Node in Linked List"
and here is my code:
#define STACK_SIZE (10000U)
typedef struct ListNode Node;
static int stack[STACK_SIZE];
static int top=-1;
bool isEmpty()
{
return (top==-1);
}
void addToStack(int element)
{
stack[++top]=element;
}
void remFromStack()
{
--top;
}
int getStackTop()
{
return stack[top];
}
typedef struct ListNode Node;
int* nextLargerNodes(struct ListNode* head, int* returnSize) {
if (head == NULL) {
*returnSize = 0;
return NULL;
}
int len = 0;
Node *temp = head;
while (temp) {
len++;
temp = temp->next;
}
if (len > 0) {
int *result = malloc(len * sizeof(int));
*returnSize = len;
if (result == NULL) {
return NULL;
}
int j = 0;
while (j < len) {
result[j++] = 0;
}
temp = head;
addToStack(temp->val);
j = 0;
while (temp->next) {
temp = temp->next;
j++;
if (getStackTop() > temp->val) {
addToStack(temp->val);
} else {
int i = 0;
while (!isEmpty()) {
i++;
result[j - i] = temp->val;
remFromStack();
}
addToStack(temp->val);
}
}
return result;
} else {
return NULL;
}
}
And I am getting the following error:
=================================================================
==29==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6030000
WRITE of size 4 at 0x60300000000c thread T0
#2 0x7f55143382e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.s
0x60300000000c is located 4 bytes to the left of 20-byte region [0x60300
allocated by thread T0 here:
#0 0x7f55157c22b0 in malloc (/usr/local/lib64/libasan.so.5+0xe82b0)
#3 0x7f55143382e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.s
I am not sure what's wrong here.
Tried making sure all the code is correct, and when I test the code against my own test cases, it works perfectly fine, but when I submit the code, only then I am getting this error.
Note: The returned array must be malloced, assume caller calls free().
The utility functions dont have any malloc/ calloc called in them, so, that removes them from the equation.
Sizeof behaves differently on Leetcode.
Try to use strlen (if you are using char) OR other methods to find the size of a datatype you are trying to use.
I have been working on a post fix calculator for standard input and after working on it I ended up getting a saying segmentation fault (core dumped) it doesn't say where it occurs or what caused it and after looking for an explanation of what it means I couldn't really find anything that would help me fix it. So I decided I might as well ask here this is all of the stuff I have so far.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct stack
{
int data;
struct stack *up;
};
void push( struct stack * ptr, int value)
{
struct stack * tmp;
tmp = malloc(sizeof(value));
tmp -> data = value;
tmp -> up = NULL;
}
int pop(struct stack * ptr)
{
int value;
struct stack * tmp;
tmp = ptr;
value = tmp-> data;
ptr = tmp -> up;
free(tmp);
return value;
}
int evaluate(int argc,const char * argv[],struct stack * ptr)
{
int h;
int i;
for (i = 0; i <= argc - 1; i++)
{
if (strcmp(argv[i], "M") == 0)
{
int a = pop(ptr);
int b = pop(ptr);
h = b*a;
push(ptr,h);
}
else if (strcmp(argv[i], "A") == 0)
{
printf("%s\n", "error \0");
int a = pop(ptr);
int b = pop(ptr);
h = b+a;
push(ptr,h);
}
else if (strcmp(argv[i], "D") == 0)
{
int a = pop(ptr);
int b = pop(ptr);
h = b/a;
push(ptr,h);
}
else if (strcmp(argv[i], "S") == 0)
{
int a = pop(ptr);
int b = pop(ptr);
h = b-a;
push(ptr,h);
}
else
{
printf("%s", "Not an operator");
}
}
return pop(ptr);
}
int main(int argc, const char *argv[])
{
struct stack s;
struct stack *ptr = s.up;
evaluate(argc,argv,ptr);
return EXIT_SUCCESS;
}
In main you create struct stack s; and don't initialize it.
Then you pass s.up as the third argument of evaluate.
And evaluate eventually calls pop on s.up, which calls free on s.up. But s.up is still uninitialized, so it crashes.
It's because you are allocating the structs wrong, here
tmp = malloc(sizeof(value));
you are allocating enough space for a int value, so the code that follows invokes undefined behavior leading in your case to a segmentation fault, try it this way
tmp = malloc(sizeof(struct stack));
or
tmp = malloc(sizeof(*tmp));
also, always check the success of malloc() before dereferencing the pointer, like this
void push(struct stack *ptr, int value)
{
struct stack *tmp;
tmp = malloc(sizeof(*tmp));
if (tmp == NULL)
return;
tmp->data = value;
tmp->up = NULL;
}
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.