Push and Pop function [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Im trying to replicate the push and pop functions using integers and an int array. However Im having trouble with finding the size of the array in the push function. How would I find the size or 'push' a new value into the array
typedef int data_t;
int
main(int argc, char **argv){
int *S, i;
S = malloc(10*sizeof(int));
S = NULL;
push(1,S);
push(3,S);
for(i = 0; S[i]; i++){
printf("%d\n",S[i]);
}
return 0;
}
void
push(data_t n,int *S ){
int size = 0, i = 0;
if (S == NULL){
S[0] = n;
}
else{
while(S[i] != NULL){
size++;
i++;
}
S[size] = n;
}
}

You first allocate an array of ten integers and assign the pointer to S. You then reassign S, making it point to NULL. That is not a valid pointer you can dereference. Dereferencing a null-pointer leads to undefined behavior.
You need to keep the size of the stack separately, and pass it along to the functions. Or use a structure containing both the pointer and the size.

I've written the below code on the fly! It seems to run good! It implements a stack management with stack overflow/underflow controls.
The main contains code to demonstrate the use of all the stack functions:
int initStack(StackType * stack, size_t numOfElement);
int freeStack(StackType * stack);
int push(StackType * stack, int value);
int mayPush(StackType *stack);
int pop(StackType * stack, int * value);
int pop2(StackType * stack);
int mayPop(StackType *stack);
StackError getError(StackType * stack);
The code uses the following basic stack operations:
stack init: sp="stack dimension".
push: stack[--sp]=value;
pop: stack[sp++]=value;
Stack overflow: (sp==0) [when we try to push a value]
Stack underflow: (sp=="stack dimension") [when we try to pop a value]
The code:
#include <stdio.h>
#include <malloc.h>
typedef enum {
NO_ERROR,
MEMORY_ERROR,
STACK_OVERFLOW,
STACK_UNDERFLOW
} StackError;
typedef struct {
int * stack;
size_t numOfElem;
size_t sp; //stack pointer
StackError err;
} StackType;
int initStack(StackType * stack, size_t numOfElement);
int freeStack(StackType * stack);
int push(StackType * stack, int value);
int mayPush(StackType *stack);
int pop(StackType * stack, int * value);
int pop2(StackType * stack);
int mayPop(StackType *stack);
StackError getError(StackType * stack);
int initStack(StackType * stack, size_t numOfElement)
{
if ( (stack->stack=malloc(sizeof(*stack->stack)*numOfElement))==NULL ) {
stack->err=MEMORY_ERROR;
return stack->err;
}
stack->err=NO_ERROR;
stack->numOfElem=numOfElement;
stack->sp=numOfElement; //The stack is void!
return stack->err;
}
int freeStack(StackType * stack)
{
if (stack->stack==NULL){
stack->err=MEMORY_ERROR;
return stack->err;
}
stack->err=NO_ERROR;
free(stack->stack);
stack->stack=NULL;
return stack->err;
}
int push(StackType * stack, int value)
{
if (stack->stack==NULL) {
stack->err=MEMORY_ERROR;
return stack->err;
}
if (!stack->sp) {
stack->err=STACK_OVERFLOW;
return stack->err;
}
stack->err=NO_ERROR;
stack->stack[--stack->sp]=value;
return stack->err;
}
int pop(StackType * stack, int * value)
{
if (stack->stack==NULL) {
stack->err=MEMORY_ERROR;
return stack->err;
}
if (stack->sp>=stack->numOfElem) {
stack->err=STACK_UNDERFLOW;
return stack->err;
}
stack->err=NO_ERROR;
*value=stack->stack[stack->sp++];
return stack->err;
}
int pop2(StackType * stack)
{
int value;
pop(stack,&value);
return value;
}
int mayPush(StackType *stack)
{
return (stack->stack!=NULL && stack->sp>0)?1:0;
}
int mayPop(StackType *stack)
{
return (stack->stack!=NULL && stack->sp<stack->numOfElem)?1:0;
}
StackError getError(StackType * stack)
{
return stack->err;
}
int main(void)
{
StackType stack;
int res,i,j;
size_t max=20;
if ( (res=initStack(&stack, max))!=NO_ERROR ) {
printf("Error: %d\n",res);
return res;
}
//Fill the stack;
printf("Pushing: ");
i=0;
while(mayPush(&stack)) {
push(&stack,++i);
printf("%d ",i);
}
puts("");
//Try to push another element into the stack
res=push(&stack,i);
if (res!=NO_ERROR) {
printf("Push error: %d\n",res);
}
//Read all the stack
printf("Popping: ");
while(mayPop(&stack)) {
printf("%d ",pop2(&stack));
}
puts("");
//Try to pop another element into the stack form 1
res=pop(&stack,&i);
if (res!=NO_ERROR) {
printf("Pop error: %d\n",res);
}
//Try to pop another element into the stack form 2
i=pop2(&stack);
res=getError(&stack);
if (res!=NO_ERROR) {
printf("Pop error: %d\n",res);
}
//Fill an half of the stack
printf("Pushing: ");
for(i=1;i<=(int)max/2;i++) {
push(&stack,i);
printf("%d ",i);
}
puts("");
//Get some value from the stack
printf("Popping: ");
for(i=1;i<=(int)max/4;i++) {
printf("%d ",pop2(&stack));
}
puts("");
//Put some value in the stack (also generates errors)
for (j=0;j<3;j++) {
printf("Pushing: ");
for(i=1;i<=(int)max/3;i++) {
printf("%d ",i*3+j);
if ( (res=push(&stack,i*3+j))!=NO_ERROR ) {
printf("Push error: %d\n",res);
}
}
puts("");
}
//Get some value from the stack (also generates errors)
printf("Popping: ");
for(i=0;i<(int)max+2;i++) {
if ( (res=pop(&stack,&j))!=NO_ERROR ) {
printf("\nPop error: %d",res);
} else {
printf("%d ",j);
}
}
puts("");
puts("Deallocating the stack!");
freeStack(&stack);
printf("Pushing: ");
if ( (res=push(&stack,415))!=NO_ERROR ) {
printf("Push error: %d\n",res);
}
puts("Re-Deallocating the stack!");
if ( (freeStack(&stack))!=NO_ERROR ) {
printf("freeStack Error: %d\n",res);
}
return 0;
}

Firstly, so glad to see that you didn't cast the result of malloc.
Your
int
main(int argc, char **argv){
Be assured that it doesn't have any side effect on the code behaviour, but as I have seen most of the people doing it this way, improves readability. should be,
int main(int argc, char **argv){
This
S = malloc(10*sizeof(int));
S = NULL;
should be
S = NULL;
S = malloc(10*sizeof(int));
I don't comprehend what you are trying through this:
for(i = 0; S[i]; i++)
May be this should be something like,
for(i = 0; i < MAX_LENGTH; i++) //MAX_LENGTH should be some integer #defined somewhere in the code
Apart from these obvious mistakes, you can actually think about adding a check to ensure that, in the while loop in the function push() you don't overrun the value of size than what s can accommodate.
Then, instead of doing
if (S == NULL){
S[0] = n;
}
in push(), I would have preferred checking if the memory is allocated after malloc. So,
S = malloc(10*sizeof(int));
if (S == NULL)
{
//Error handling supposed to be done if no memory is allocated
}
This should do what you are looking forward to:
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
int top;
void push(data_t,int*);
int pop(int*);
int
main(int argc, char **argv)
{
int *S = NULL, i;
top = -1;
S = malloc(10*sizeof(int));
if(S == NULL)
{
printf("Memory Allocation failed");
//other error handling implementation if any
}
push(1,S);
push(2,S);
push(3,S);
for(i = 0; i <= top; i++){
printf("%d\n",S[i]);
}
printf("\n Popping:\n");
pop(S);
for(i = 0; i <= top; i++){
printf("%d\n",S[i]);
}
return 0;
}
void
push(data_t n,int *S )
{
//Check if Stack is full
if (top == 10)
{
printf("Stack Full");
//other implementation
}
else
{
++top;
S[top] = n;
}
}
int
pop(int *S)
{
//Check if Stack is empty
if (top == -1)
{
printf("Stack Empty");
//other implementation
}
else
{
return S[top--];
}
}
The code is untested as I am travelling.

Related

Can't identify memory access error in code, keeps giving segmentation faults

I have tried creating a program that uses simple stack functions like push to add the contents of the statement onto a stack from where I then print out each character and then reverse the statement. I have used the '.' and '->' member access variables to change the contents of the struct based stack. Upon compiling it prints out the original statement, but after that it gives a segmentation error, saying I am attempting to dereference an uninitialised pointer. Can someone guide me as to how I should solve this problem as it isn't stating the line I have made the problem either.
#include <stdio.h>
#define MAX 1000
#define FULL (MAX - 1)
#define EMPTY -1
typedef struct stack {char s[MAX]; int top;} stack;
int top = EMPTY;
int isFull()
{
if(top == FULL)
return 1;
else
return 0;
}
int isEmpty()
{
if(top == EMPTY)
return 1;
else
return 0;
}
void reset(stack *stk)
{
stk -> top = EMPTY;
}
void push(char c, stack *stk)
{
stk -> top++;
(*stk).s[(*stk).top] = c;
}
char pop(stack *stk)
{
return (*stk).s[(*stk).top--];
}
void print(stack *stk)
{
int i;
while(1)
{
if(isEmpty())
{
printf("Stack underflow\n");
break;
}
for(i = 0; i <= top; i++)
{
printf("%c\n", (*stk).s[i]);
}
printf("\n");
return;
}
}
void reverse(stack *stk)
{
int i;
while(1)
{
if(isEmpty())
{
printf("Stack underflow\n");
break;
}
for(i = top; i >= 0; i--)
{
printf("%c", (*stk).s[i]);
}
printf("\n");
return;
}
}
char peek(const stack *stk)
{
while(1)
{
if(isEmpty())
{
printf("Stack underflow\n");
break;
}
return (*stk).s[(*stk).top];
}
}
int main()
{
stack stack_of_char;
char *str = "i am otto am i";
int i;
reset(&stack_of_char);
printf("original is: %s\n", str);
while(str[i] != '\0')
{
push(str[i++], &stack_of_char);
}
print(&stack_of_char);
reverse(&stack_of_char);
return 0;
}
There are several issues with your program. Let's begin with the global variable top. This is causing problems because on the one hand you have a stack struct responsible for maintaining a stack, and that has its own top. But then you have this global which you're not even using anywhere. It's almost like you added it to get around compiler errors that you didn't understand ;)
So let's ditch that, and fix your stack functions. I'm rearranging the parameters of the push function so that the stack is the first argument. This is a bit more conventional.
typedef struct stack {
char s[MAX];
int top;
} stack;
int isFull(stack *stk)
{
return stk->top == FULL;
}
int isEmpty(stack *stk)
{
return stk->top == EMPTY;
}
void reset(stack *stk)
{
stk->top = EMPTY;
}
void push(stack *stk, char c)
{
if (isFull(stk))
return;
stk->s[++stk->top] = c;
}
char pop(stack *stk)
{
if (isEmpty(stk))
return '\0';
return stk->s[stk->top--];
}
For the pop function, I arbitrarily return a NUL character if the stack is empty, because something must be returned. But really, you should never call this function if the stack is empty.
Let's look at your display functions now. The first thing I notice is that these are really convoluted. There is no need for that complexity. Look here:
void print(stack *stk)
{
for(int i = 0; i <= stk->top; i++)
{
printf("%c\n", stk->s[i]);
}
printf("\n");
}
void reverse(stack *stk)
{
for(int i = stk->top; i >= 0; i--)
{
printf("%c", (*stk).s[i]);
}
printf("\n");
}
char peek(const stack *stk)
{
if (isEmpty(stk))
{
printf("Stack empty!\n");
return '\0';
}
return stk->s[stk->top];
}
And so all that remains is a little tidy-up of your main function, and adjust the parameter order for push.
int main()
{
const char *str = "i am otto am i";
printf("original is: %s\n", str);
stack stack_of_char;
reset(&stack_of_char);
for (int i = 0; str[i]; i++)
{
push(&stack_of_char, str[i]);
}
print(&stack_of_char);
reverse(&stack_of_char);
}
Note also that you shouldn't really be walking over your stack with those functions. The typical way you would use a stack to reverse something is to push values onto it and then pop them off. So, you can print the string in reverse like this:
// Pop characters from stack to print in reverse
while (!isEmpty(&stack_of_char))
{
char c = pop(&stack_of_char);
putc(c, stdout);
}
putc('\n', stdout);
Without initialization, the integer will be a random value. It is the root cause of the memory access error.
You will need to initialize the variable properly. In main function, instead of
int i;,
you should use
int i = 0;.
Assume that you plan to access the value starting from index 0.

Why does calling a function modify the value of an array of pointer to function that weren't given in parameter?

I've got a struct that contains a pointer to function and an array of pointers to function. I'm passing the first pointer (not the array) as parameter of a function which is supposed to tell me whether an array of integers is sorted or not (it can be in ascending or descending order and this is defined by compFct, which is the pointer to function given in parameter).
Unfortunately that function is changing the values in the array of pointers in my struct (without changing the value of my pointer to function given in parameter).
Using gdb I managed to know when were made the changes in my array. It appears to be modified after the first printf in the printSorted function.
My typedef :
typedef int (*PtrCompFct)(int, int);
typedef int (*PtrSortFct)(int*, int, int, PtrCompFct);
The struct :
typedef struct
{
int nbFct;
PtrCompFct compFct;
PtrSortFct *sortFct;
} SortCompFct_s;
Here is how I'm calling my function (userChoices is of SortCompFct_s type):
printSorted(myArr, myArrSize, userChoices->compFct);
And the fonction that is changing my structure :
int printSorted(int *arr, int arrSize, PtrCompFct compFct)
{
for (int i=0; i<(arrSize-1); i++)
{
if (compFct(arr[i+1], arr[i]))
{
//this is when my array of pointers to function is modified
printf("The array isn't sorted\n\n");
return 0;
}
}
printf("The array is sorted\n\n");
return 1;
}
With gdb before the printf I have :
(gdb) print main::userChoices->sortFct[0]
$36 = (PtrSortFct) 0x5555555548ea <quickSort>
and after :
(gdb) print main::userChoices->sortFct[0]
$37 = (PtrSortFct) 0x7fffffffddc0
As you can see the pointer to my quickSort function has been modified.
EDIT : include of the simplified and verifiable code, the thing is that this code is working properly, even with the printSorted function
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef int (*PtrCompFct)(int, int);
typedef int (*PtrSortFct)(int*, int, int, PtrCompFct);
typedef struct
{
int nbFct;
PtrCompFct compFct;
PtrSortFct *sortFct;
} SortCompFct_s;
typedef SortCompFct_s *PtrSortCompFct_s;
void initTab(int *arr, int arrSize)
{
time_t t;
srand(time(&t));
for (int i=0; i<arrSize; i++)
{
arr[i] = rand();
}
}
int ascendingSort(int elmt1, int elmt2)
{
return (elmt1 < elmt2);
}
int descendingSort(int elmt1, int elmt2)
{
return (elmt1 > elmt2);
}
void switche(int *arr, int ind1, int ind2)
{
int temp = arr[ind1];
arr[ind1] = arr[ind2];
arr[ind2] = temp;
}
int bubbleSort(int *arr, int ind1, int ind2, PtrCompFct fctComp)
{
int sorted;
for (int i=ind1; i<ind2; i++)
{
sorted = 1;
for (int j=0; j<ind2; j++)
{
if (fctComp(arr[j+1], arr[j]))
{
switche(arr, j, j+1);
sorted = 0;
}
}
if (sorted) return 0;
}
return 0;
}
void printArr(int *arr, int arrSize)
{
for (int i=0; i<arrSize; i++)
{
printf("%16d\n", arr[i]);
}
}
int printSorted(int *arr, int arrSize, PtrCompFct compFct)
{
for (int i=0; i<arrSize-1; i++)
{
if (compFct(arr[i+1], arr[i]))
{
//this is when my array of pointers to function is modified
printf("The array isn't sorted\n\n");
return 0;
}
}
printf("The array is sorted\n\n");
return 1;
}
PtrSortCompFct_s menu(void)
{
PtrSortCompFct_s userChoices;
PtrSortFct arrSortFct[] = {bubbleSort};
if ((userChoices = malloc(3*sizeof(int))) != NULL)
{
userChoices->nbFct = 1;
userChoices->compFct = ascendingSort;
userChoices->sortFct = arrSortFct;
}
return userChoices;
}
int main(void)
{
int arrSize = 10;
int arr[arrSize];
initTab(arr, arrSize);
PtrSortCompFct_s userChoices;
if ((userChoices = malloc(3*sizeof(int))) != NULL) userChoices = menu();
printArr(arr, arrSize);
printSorted(arr, arrSize, userChoices->compFct);
userChoices->sortFct[0](arr, 0, arrSize-1, userChoices->compFct);
printArr(arr, arrSize);
printSorted(arr, arrSize, userChoices->compFct);
return 0;
}
With gdb before the printf I have: ... and after:
The root cause of your problem is in how you have initialized userChoices->sortFct (you have not shown the code which performs this initialization).
That array is pointing to dangling heap or stack memory, and a call to printf overwrites that memory.
if ((userChoices = malloc(6*sizeof(int))) != NULL) userChoices = menu();
That code is completely bogus: heap-allocating memory for userChoices and then immediately overwriting userChoices with return value from menu() only serves to leak memory. As mentioned in the comments, 6*sizeof(int) is also completely bogus size.
I would guess that your menu() looks something like this:
struct SortCompFct_s* menu()
{
struct SortCompFct_s ret;
ret.compFct = &SomeFunc;
ret.sortFct = malloc(...);
ret.sortFct[0] = &quickSort;
return &ret; // Oops: returning address of a local!
}
If that is in fact what you did, dangling stack is exactly your problem. You should turn on maximum compiler warnings (-Wall -Wextra if using GCC), so the compiler tells you you are doing something wrong.
Update:
My guess was close:
PtrSortCompFct_s menu(void)
{
PtrSortCompFct_s userChoices;
PtrSortFct arrSortFct[] = {bubbleSort};
if ((userChoices = malloc(3*sizeof(int))) != NULL)
{
userChoices->nbFct = 1;
userChoices->compFct = ascendingSort;
userChoices->sortFct = arrSortFct;
}
return userChoices;
}
The problem is that userChoices->sortFct points to a local (stack) variable arrSortFct. That local variable becomes invalid after return from menu, and at that point userChoices->sortFct is pointing to dangling stack (as I guessed).
Here is correct way to write this function (omitting error checking of malloc return for clarity):
PtrSortCompFct_s menu(void)
{
PtrSortCompFct_s userChoices;
PtrSortFct arrSortFct[] = {bubbleSort};
if ((userChoices = malloc(sizeof(*userChoices)) != NULL)
{
userChoices->nbFct = 1;
userChoices->compFct = ascendingSort;
userChoices->sortFct = malloc(sizeof(arrSortFct));
memcpy(userChoices->sortFct, arrSortFct, sizeof(arrSortFct));
}
return userChoices;
}
You should also need to fix your main like so:
PtrSortCompFct_s userChoices;
PtrSortCompFct_s userChoices = menu();
... use userChoices ...
free(userChoices->sortFct);
free(sortFct);
return 0;

How to use multiple data types within the same ADT in C?

For example, if I defined a Stack ADT in C, normally my type definition -using an array based implementation- is like this:
typedef char StackEntry;
typedef struct stack {
int top;
StackEntry entry[MAXSTACK];
} Stack;
How can I make my Stack such that I can have one Stack for characters and another Stack -in the same program- that handles integers for example ?
You could use a stack-structure that is initialized with the size of the elements and that reserves a memory block in terms of bytes to store the elements:
typedef struct stack {
int top;
size_t size;
size_t maxElems;
char content[];
} Stack;
Stack *createStack(size_t size, size_t maxElems) {
Stack *result = malloc(sizeof(Stack)+size*maxElems);
result->top=0;
result->size=size;
result->maxElems=maxElems;
return result;
}
int push(Stack *stack, void *elem) {
if (stack->top == stack->maxElems)
return -1;
memcpy(stack->content + stack->top * stack->size, elem, stack->size);
stack->top++;
return stack->top;
}
int pop(Stack *stack, void *elem) {
if (stack->top == 0)
return -1;
stack->top--;
memcpy(elem, stack->content + stack->top * stack->size, stack->size);
return stack->top;
}
int main() {
Stack *charStack = createStack(sizeof(char), 10);
for (int i=0; i<10; i++) {
char c = 'A'+i;
push(charStack, &c);
}
char c;
while (pop(charStack, &c) >= 0) {
printf("%c\n", c);
}
free(charStack);
Stack *intStack = createStack(sizeof(int), 10);
for (int i=0; i<10; i++) {
push(intStack, &i);
}
int i;
while (pop(intStack, &i) >= 0) {
printf("%d\n", i);
}
free(intStack);
}
Use macros, e.g.
#define STACK_TYPE(type) struct { int top; type entry[MAXSTACK]; }
You may well end up using macros for the stack operations such as push/pop too:
#define STACK_PUSH(stack, value) \
do { if ( (top) < MAXSTACK ) (stack).entry[(stack).top++] = (value); } while (0)
In most cases you wouldn't need to pass the stack type as a macro parameter, since the same syntax works for all stacks.
Sample usage:
STACK_TYPE(int) mystack = { 0 };
STACK_PUSH(mystack, 5);
Obviously there are a lot of different ways you could do the details.

free stack function errors normally, but not when setting breakpoint

I'm trying to create a stack using a dynamic array and I'm getting an error when I try to run the DeleteStack() function, however, if I set a breakpoint before the function and run the main program up till that point, then continue past it, it executes properly. Would someone please tell me what I'm doing wrong and why I'm seeing this behavior?
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "dynamic_array_stack.h"
int main() {
// create stack
DynArrayStack *S = CreateStack();
// fill stack
for (int i = 1; i <= 10; i++)
Push(S, i);
// try pushing past capacity, no error (realloc's)
Push(S, 42);
// top of stack
printf("Top of stack is %d\n", Top(S));
// pop all elements of stack
while (Top(S) != INT_MIN) {
printf("%d\n", Pop(S));
}
// delete stack, check pointer again
DeleteStack(S);
return 0;
}
dynamic_array_stack.h:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef struct dynarraystack {
int top;
int capacity;
int *array;
} DynArrayStack;
DynArrayStack* CreateStack() {
DynArrayStack* S = malloc(sizeof(DynArrayStack));
if (!S) {
printf("Error: Could not create stack.\n");
return NULL;
}
S->capacity = 1;
S->top = -1;
S->array = malloc(S->capacity * sizeof(int));
if (!S->array) {
printf("Error: could not create stack.\n");
return NULL;
}
return S;
}
int isFullStack(DynArrayStack *S) {
return (S->top == S->capacity-1);
}
void DoubleStack(DynArrayStack *S) {
S->capacity *= 2;
S->array = realloc(S->array, S->capacity);
}
void Push(DynArrayStack *S, int data) {
if (isFullStack(S))
DoubleStack(S);
S->array[++S->top] = data;
}
int isEmptyStack(DynArrayStack *S) {
return S->top == -1;
}
int Top(DynArrayStack *S) {
if(isEmptyStack(S))
return INT_MIN;
return S->array[S->top];
}
int Pop(DynArrayStack *S) {
if (isEmptyStack(S)) {
printf("Array is empty. Returning INT_MIN.\n");
return INT_MIN;
}
return S->array[S->top--];
}
void DeleteStack(DynArrayStack *S) {
if (S) {
if (S->array)
free(S->array);
free(S);
printf("Stack deleted.\n");
}
}
edit: Actually it only does not error if I set two breakpoints, one before the while loop (so I step through it manually), and another before the DeleteStack() function. Still confused though.

Error in printing the stack

I am trying to implement a program using stacks.But the stack is not getting displayed
#include<stdio.h>
int size=0,count=1,test=0;
struct Car
{
int registrationNo;
char *name;
};
struct ParkingLot
{
struct Car C[10];
};
struct stack
{
struct ParkingLot P;
int top;
} st;
int stfull()
{
if(st.top >= size-1)
return 1;
else
return 0;
}
void push(struct Car item) {
st.top++;
st.P.C[st.top] = item;
}
int stempty() {
if (st.top == -1)
return 1;
else
return 0;
}
void display() {
int i;
if (stempty())
printf("\nStack Is Empty!");
else {
//printf("%d\n",st.top);
for (i = 0; i<=st.top; i++)
printf("\n%s", st.P.C[i].name);
}
}
void Enter_ParkingLot()
{
struct Car CC;
int checkFull=stfull();
if(checkFull==1)
printf("Parking Lot is FUll\n");
else
{
CC.registrationNo=count;count++;
char ch[100];
printf("Enter name of owner\n");
scanf("%s",ch);
CC.name=ch;
push(CC);
}
}
int main()
{
printf("Enter size of Parking Lot\n");
st.top=-1;
scanf("%d",&size);
Enter_ParkingLot();
Enter_ParkingLot();
display();
return 0;
}
This was my input on terminal-
Enter size of Parking Lot
2
Enter name of owner
ABCD
Enter name of owner
EFGH
This was my output-
`#
`#
There was a blank line before first # in the output.
If you assign the pointer field in struct Car to a local variable, it will not work, you need to redeclare your struct Car like this
struct Car
{
int registrationNo;
char name[100];
};
and then instead of
CC.name=ch;
do it this way
strcpy(CC.name, ch);
also, it's better to write
scanf("%99s",ch);
to prevent overflowing ch, and in your case it would be even better to do
scanf("%99s", CC.name);
I fixed your code
#include <stdio.h>
#include <string.h>
struct Car
{
int registrationNo;
char name[100];
};
struct ParkingLot
{
struct Car C[10];
};
struct stack
{
struct ParkingLot P;
int top;
} st;
int stfull(int size)
{
if(st.top >= size - 1)
return 1;
return 0;
}
void push(struct Car item)
{
st.P.C[++(st.top)] = item;
}
int stempty()
{
if (st.top == -1)
return 1;
return 0;
}
void display()
{
int i;
if (stempty() != 0)
printf("\nStack Is Empty!");
else {
for (i = 0 ; i <= st.top ; i++)
printf("\n%s", st.P.C[i].name);
}
}
int Enter_ParkingLot(int count, int size)
{
struct Car CC;
if (stfull(size) == 1)
printf("Parking Lot is FUll\n");
else
{
CC.registrationNo = count;
printf("Enter name of owner\n");
scanf("%99s", CC.name);
push(CC);
}
return count + 1;
}
int main()
{
int size = 0, count = 1;
printf("Enter size of Parking Lot\n");
st.top = -1;
scanf("%d", &size);
count = Enter_ParkingLot(count, size);
count = Enter_ParkingLot(count, size);
display();
return 0;
}
I removed global variables, they where not needed.
I fixed some if/else's which made no sense.
I also applied my previously suggested fixes related to your original problem.
The Problem:
You store the name of the car into an array that is allocated on the stack.
You then copy the pointer to that array to your car object.
The original array then goes out of scope.
You then try to print that array, which no longer exists, via the pointer.
Undefined behavior occurs.
The Solution:
You need to allocate memory for the name of the car with malloc() and use strcpy() to copy it to the car object.

Resources