Kalkulator ONP - naruszenie ochrony pamięci

0

Witam, mam problem z programem na kalkulator ONP. Kompiluje się on poprawnie, jednakże podczas wykonywania działań, np 2 3 + q, wyskakuje naruszenie ochrony pamięci. Nie bardzo wiem gdzie leży błąd, być może coś jest nie tak z poszczególnymi opcjami wyboru znaków lub coś nie tak z funkcjami pop/push... Przeszukiwałem już wiele tematów na tym forum i innym, ale nigdzie nie znalazłem satysfakcjonującej mnie odpowiedzi. Bardzo proszę o jakąś pomoc, ewentualnie wytłumaczenie co trzeba zrobić.. * Bardzo proszę też osoby, które czytają to tylko po to, żeby odpisać coś w stylu 'wszystko znajdziesz w internecie', o nie tracenie swojego i mojego czasu, dopiero zacząłem uczyć się struktur, stosów, list itp i na tyle ile mogłem ogarnąłem temat samemu, teraz potrzebuje pomocy na konkretnym przykładzie. Dziękuję, pozdrawiam.*

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

typedef struct t_elem
{
  int dana; 
  struct elem *nast;
} t_elem;


/* funkcja wkładająca liczbę na stos */
int push(t_elem **stos, int elem)
{
  t_elem *tmp;
  tmp = (t_elem*)malloc(sizeof(t_elem));
  tmp->dana=elem;
  if(*stos)
      tmp->nast = *stos;
  else
    tmp->nast = 0; 
  *stos = tmp;
}

/*funkcja zdejmująca liczbę ze stosu*/
int pop(t_elem **stos, int *elem)
{
  t_elem *tmp;
  tmp=*stos;
  *stos = (*stos)->nast;
  free(tmp);
}

/* funkcja wyświetlająca liczby na stosie */
void print(t_elem **stos)
{
  t_elem *tmp;
  tmp=*stos;
  if((tmp)==NULL)
    {
      printf("Stos jest pusty");
    }
  printf("Liczby na stosie:\n");
  do{
    printf("%d\n", tmp -> dana);
    tmp=tmp->nast;
    }
  while (tmp != NULL);
}

int empty(t_elem **stos, int elem)
{
return !(*stos);
}

int main(){
  int zm1, zm2;
  t_elem *stos = NULL;
  int elem;
  char oper;
  printf("Kalkulator ONP:\n");
  printf("Podaj działanie w postaci ONP\n");
  while(oper != 'q') /*rób dopóki nie zostanie wprowadzona literka q*/
   {
   
    oper = getc(stdin);
    ungetc(oper, stdin);

    if(oper <= '9' && oper >= '0')
      {
	scanf("%d\n", &elem);
	push(&stos, elem);
      }
   
    if(oper == '#') /*usunięcie ostatnio wprowadzonej liczby*/
      {
	pop(&stos, &elem);
	getc(stdin);
      }
    
    if(oper == '?') /*wydrukowanie na ekran zawartości całego stosu*/
      {
	print(&stos);
	getc(stdin);
      }
    
    if (oper == '$') /*zamiana miejscami dwóch argumentów, znajdujących się na szczycie stosu*/
      {
	zm1=(stos)->dana;
	pop(&stos, &elem);
	zm2=(stos)->dana;
	pop(&stos, &elem);
	push(&stos, zm1);
	push(&stos, zm2);
      }
    
    if (oper=='&') /*zduplikowanie argumentu znajdującego się na szczycie stosu*/
      {
	zm1=(stos)->dana;
	pop(&stos, &elem);
	push(&stos, zm1);
	push(&stos, zm1);
      }
    
    if (oper == '-') /*operacja odejmowania*/
      {
	zm1=(stos)->dana;
	pop(&stos, &elem);
	zm2=(stos)->dana;
	pop(&stos, &elem);
	push(&stos, zm2-zm1);
      }
   
    if (oper == '+') /*operacja dodawania*/
      {
	zm1=(stos)->dana;
	pop(&stos, &elem);
	zm2=(stos)->dana;
	pop(&stos, &elem);
	push(&stos, zm1+zm2);
      }
    
    if (oper == '*') /*operacja mnożenia*/
      {
	zm1=(stos)->dana;
	pop(&stos, &elem);
	zm2=(stos)->dana;
	pop(&stos, &elem);
	push(&stos, zm1*zm2);
      }
    
    if (oper == '/') /*operacja dzielenia*/
      {
	zm1=(stos)->dana;
	pop(&stos, &elem);
	zm2=(stos)->dana;
	pop(&stos, &elem);
	push(&stos, zm2/zm1);
      }

}
return 0;
}
0

Odpal to pod debugerem i leć linijka po linijce aż znajdziesz bląd. Nikt tego za ciebie nie zrobi. Poza tym TEN SAM KOD był tutaj już poprawiany raptem z tydzień temu (tzn zakładam że zadanie od tego samego prowadzącego...). Sam go poprawiałem...

http://4programmers.net/Forum/C_i_C++/245326-ansi_c_stos_-_dodawanie_i_zdejmowanie_elementu_wyswietlanie_stosu?p=1102441

0

Ok, dzięki za link. Nie znalazłem akurat tego tematu..Na podstawie tego co tam jest, postaram się ogarnąć swój program. Jakby co to się odezwę :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1