Re: Stack



On Sat, 05 Jan 2008 01:52:33 +0530, Tarique <peo_leo@xxxxxxxxx> wrote:

Tarique wrote:
Hello all.I am trying to implement a stack which can store either
integer or float values.

The code is given below:
...snip...

Here is the final code:
Works fine in case of Integer n floats.However i lose track of the
character pointer once i exit the push function (in case of strings).
So in case of *Strings* i cannot display the popped string or the
members of the stack at any given time.
Using an extra global variable to keep track also does not help!
It's confusing!!!

Actually it is a very common mistake. When you are attempting to
build a stack of strings, you store your data in various instances of
the member pVal of the union. pVal is a pointer. It holds an address
and not the contents of the string. The address that you store in
this pointer is the address of the array cValue in the function push.
This causes at least two problems:

The first is that cValue is an automatic object. It gets
created when push is entered AND destroyed when push returns. As soon
as push returns, the address you stored in pVal becomes indeterminate
by definition. Any future attempt you make to evaluate this address
causes undefined behavior.

The second is that even if you gave cValue a life span that
survived multiple calls to push, such as declaring it static, it would
only contain the value from the last call to push. This would
eliminate the undefined behavior. But every instance of pVal would be
pointing to the same address. When you go to print the stack
contents, you would be printing the exact same data for every stack
element.

There are methods for solving the problem:

You could change pVal so it was an array the same size as
cValue. Then you could use strcpy to copy the string itself, not its
address, into pVal.

Instead of using a defined array, you could use malloc to
dynamically allocate space for each new string and store the address
of this new memory in pVal.


PS:ive not really bothered about scanf..Will change that :)



#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define STACKSIZE 100
#define INT 1
#define FLOAT 2
#define STRING 3

struct stackelement{
int etype; /*etype equals INT,FLOAT,STRING*/
/*depending on the type of the */
/*corresponding element */
union {
int iVal;
float fVal;
char *pVal;
}element;
};

struct stack{
int top;
struct stackelement item[STACKSIZE];
};

void push(struct stack *p,struct stackelement *se)
{
int test;
int iValue = 0;
float fValue = 0.0;
char cValue[10];

printf("Enter the number/character to push");
if(se->etype == INT)
scanf("%d",&iValue);
else if(se->etype == FLOAT)
scanf("%f",&fValue);
else if(se->etype == STRING)
{
while((test=getchar())!='\n')
;
fgets(cValue,10,stdin);
}


if(p->top == STACKSIZE-1 )

You should make this test prior to asking the user for input.

printf("overflow\n");

else
{
if(se->etype == INT)
p->item[++p->top].element.iVal=iValue;
else if(se->etype == FLOAT)
p->item[++p->top].element.fVal=fValue;
else if(se->etype == STRING)
p->item[++p->top].element.pVal=cValue;
}
return;
}

void pop(struct stack *p,struct stackelement *se)
{
if(p->top==-1)
printf("underflow\n");
else
{
if(se->etype == INT)
printf("Deleted Integer is\ %d\n",p->item[p->top].element.iVal);
else if(se->etype == FLOAT)
printf("Deleted Float is\ %f\n",p->item[p->top].element.fVal);
else if(se->etype == STRING)
printf("Deleted String is\ %s\n",p->item[p->top].element.pVal);


--p->top;
}
return;
}


void display(struct stack *p,struct stackelement *se)
{
int i;
if(p->top == -1)
printf("Stack is Empty\n\n");
else
{
if(se->etype == INT)
{
for(i=p->top; i >= 0; i--)
printf("%d\n", p->item[i].element.iVal );
}

else if(se->etype == FLOAT)
{
for(i = p->top; i >= 0; i--)
printf("%f\n", p->item[i].element.fVal);
}

else if(se->etype == STRING)
{
for(i = p->top; i >= 0; i--)
printf("%s\n",p->item[p->top].element.pVal);
}
/*((((*(p)).item)[0]).element).pVal*/
}
return;
}

void menu(struct stack *s,struct stackelement *s_elem)
{
int num=0;
int choice;
int flag=1;

while(flag)
{
printf("Menu");
printf("\n1.Push");
printf("\n2.Pop");
printf("\n3.Display");
printf("\n4.Exit");
printf("\n5.Clear screen\n");
printf("Enter your choice :");
scanfs("%d",&choice);

switch(choice)
{
case 1:
push(s,s_elem);
system("cls");
break;
case 2:
pop(s,s_elem);
break;
case 3:
display(s,s_elem);
break;
case 4:
flag=0;
break;
case 5:
system("cls");
break;
default:
printf("wrong choice\n");
}
}
}



int main(void)
{
int choice_mm ;
struct stackelement se;
struct stack s;
s.top = -1;

for(;;)
{
printf("Choose the type of stack:\n");
printf("1.Integer\n");
printf("2.Float\n");
printf("3.String\n");
printf("4.Exit\n");
scanf_s("%i", &choice_mm);

switch(choice_mm)
{
case 1:
se.etype=INT;
system("cls");
menu(&s,&se);
system("cls");
break;
case 2:
se.etype=FLOAT;
menu(&s,&se);
break;
case 3:
se.etype=STRING;
menu(&s,&se);
break;
case 4:
exit(0);
break;
default:
printf("wrong input");
}
}
return 0;

Do you think your code can ever reach this statement?

}


Remove del for email
.



Relevant Pages

  • Re: HOWTO Implement LoadLibrary, GetProcAdress, and FreeLibrary.
    ... public static string Invoke(IntPtr IntPtr_Function, string csParam1, ... AssemblyName AssemblyName_This = new AssemblyName; ... // We must now push each paramter onto the stack. ... // We must now push the function pointer onto the stack. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: wide screen text mode?
    ... on the stack and perform a far call to the routine. ... update yx with cursor address/not 0008/0000 ... PUSH BP;save BP ... TEST AL,02H;00/01 CHAR OR 02/03 STRING? ...
    (comp.os.msdos.programmer)
  • Re: Getting a stack trace
    ... If all you want to know is the function call sequence (not the whole stack ... number or a string and then pop it off. ... function you push that function's ID to the stack, ... At error you just dump the contents of the stack to ...
    (comp.unix.programmer)
  • Re: Getting a stack trace
    ... If all you want to know is the function call sequence (not the whole stack ... number or a string and then pop it off. ... function you push that function's ID to the stack, ... At error you just dump the contents of the stack to ...
    (alt.os.linux)
  • Re: Is it wise to push all-in early in a tournament?
    ... The best times to make a push play ... But why call when you can push and take down a nice pot when your opponent ... But remember that if this "big bet" is a significant portion of your stack, ... I consider it my goal in any tournament to do the latter as much as ...
    (rec.gambling.poker)