Dynamic memory allocation not working like I want it to, any ideas why ?
I tried to allocate memory to Stack (stucture member).
But no matter what length I tried to provide, it only pushes value upto 3 elements, I can't get it.
Is the problem with Push()
, calloc()
or sizeof()
?
#include <stdio.h>
#include <stdlib.h>
typedef enum {
FALSE,
TRUE
} Boolean;
typedef struct a {
int *stack, sp;
} Stack;
int IsEmpty(Stack *s)
{
if (s->sp == -1)
{
return TRUE;
}
else
{
return FALSE;
}
}
int IsFull(Stack *s)
{
if (s->sp == sizeof(s->stack) / sizeof(int))
{
return TRUE;
}
else
{
return FALSE;
}
}
void Push(Stack *s)
{
int num;
if (IsFull(s))
{
printf("Stack Overflow\n");
}
else
{
s->sp++;
printf("Enter the Element:");
scanf("%d", &num);
s->stack[s->sp] = num;
}
}
void Pop(Stack *s)
{
if (IsEmpty(s))
{
printf("Stack Underflow\n");
}
else
{
s->sp--;
}
}
void Peek(Stack *s)
{
printf("The Element at the peak is %d", s->stack[s->sp]);
}
void Display(Stack *s)
{
if (s->sp < 1)
{
printf("Stack is empty\n");
}
else
{
for (int i = 0; i <= s->sp; i++)
{
printf("The element at the index %d is %d\n", i, s->stack[i]);
}
}
}
int Option()
{
int opt;
printf("\nSelect Option\n\n1.Push\n2.Pop\n3.Peek\n4.Display\n5.Exit\n");
scanf("%d", &opt);
return opt;
}
void EmptyStack(Stack *s)
{
int ln;
s->sp = -1;
printf("Enter the length of stack : ");
scanf("%d", &ln);
s->stack = (int *)calloc(ln, sizeof(int));
if (s == NULL)
{
printf("Insufficient Memory");
exit(0);
}
else
{
printf("Memory Allocated Successfully");
}
}
void main()
{
int opt;
Stack s;
EmptyStack(&s);
while (1)
{
opt = Option();
switch (opt)
{
case 1:
Push(&s);
break;
case 2:
Pop(&s);
break;
case 3:
Peek(&s);
break;
case 4:
Display(&s);
break;
case 5:
exit(1);
default:
printf("Invalid Choice\n");
break;
}
}
}
Any help to figure this out is appreciated, thank you!
You cannot use sizeof(s->stack)
to compute the length of the array allocated by calloc()
to which s->stack
points. You must store the length in the Stack
structure when you allocate the array.
typedef struct a {
int *stack;
int sp, len;
} Stack;
Also note that the test for IsFull
is inconsistent with your usage of the sp
index. You should check that sp
is below s->len - 1
.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
typedef struct Stack {
int *stack;
int sp, len;
} Stack;
int IsEmpty(const Stack *s) {
return (s->sp <= -1);
}
int IsFull(const Stack *s) {
return (s->sp >= s->len - 1);
}
void Push(Stack *s) {
int num;
if (IsFull(s)) {
printf("Stack Overflow\n");
} else {
printf("Enter the Element:");
if (scanf("%d", &num) == 1) {
s->sp++;
s->stack[s->sp] = num;
} else {
printf("invalid input\n");
scanf("%*[^\n]"); // consume the offending input
}
}
}
void Pop(Stack *s) {
if (IsEmpty(s)) {
printf("Stack Underflow\n");
return 0;
} else {
return s->stack[s->sp--];
}
}
void Peek(const Stack *s) {
if (IsEmpty(s)) {
printf("Stack is empty\n");
} else {
printf("The Element at the peak is %d\n", s->stack[s->sp]);
}
}
void Display(const Stack *s) {
if (IsEmpty(s)) {
printf("Stack is empty\n");
} else {
for (int i = 0; i <= s->sp; i++) {
printf("The element at the index %d is %d\n", i, s->stack[i]);
}
}
}
int Option(void) {
int opt;
printf("\nSelect Option\n\n"
"1.Push\n"
"2.Pop\n"
"3.Peek\n"
"4.Display\n"
"5.Exit\n");
if (scanf("%d", &opt) == 1) {
return opt;
} else {
printf("Invalid input\n");
scanf("%*[^\n]"); // consume the offending input
return -1;
}
}
void InitStack(Stack *s) {
int len;
printf("Enter the length of stack : ");
if (scanf("%d", &len) != 1 || len <= 0) {
printf("invalid input\n");
scanf("%*[^\n]"); // consume the offending input
exit(1);
}
s->sp = -1;
s->len = len;
s->stack = calloc(len, sizeof(*s->stack));
if (s->stack == NULL) {
printf("Insufficient Memory\n");
exit(1);
} else {
printf("Memory allocated successfully\n");
}
}
void FreeStack(Stack *s) {
free(s->stack);
s->len = 0;
s->sp = -1;
}
int main(void) {
Stack s;
InitStack(&s);
while (1) {
switch (Option()) {
case 1:
Push(&s);
break;
case 2:
Pop(&s);
break;
case 3:
Peek(&s);
break;
case 4:
Display(&s);
break;
case 5:
FreeStack(&s);
return 0;
default:
printf("Invalid choice\n");
break;
}
}
}