Cześć,
Napisałem program, a bardziej zmodyfikowałem wcześniej napisany program który działał na bazie stosu na bazie tablicy, teraz chciałem żeby działał na bazie stosu na bazie listy jednokierunkowej.
Niestety w debuggerze wywala mi Program received signal SIGSEGV, Segmentation fault. w 45 linii.
Program przestaje działać w momencie próby użycia funkcji push w 134 linii.
Debugger wypluwa dokładnie przy próbie wpisania liczby 1:
Program received signal SIGSEGV, Segmentation fault.
0x0000555555555336 in push (stos=0x0, dana=1) at main.c:45
45 stos->glowa=dodaj_poczatek(stos->glowa, dana);
Może ktoś zasugerować w czym problem? Nie jestem zbyt dobry z programowania i nie rozumiem w czym jest problem.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXOP 100 /* Dopuszczalny rozmiar liczby lub operatora */
#define NUMBER '0' /* Sygnal mowiacy ze pobrano liczbe */
#define BUFSIZE 100 /* Dopuszczalny rozmiar bufora */
typedef struct elem {
int dana;
struct elem * nast;
} t_elem;
t_elem * inicjuj() {
return NULL;
}
t_elem * tworz(int dana) {
t_elem * nowy=malloc(sizeof(t_elem));
nowy->dana=dana;
nowy->nast=NULL;
return nowy;
}
t_elem * dodaj_poczatek(t_elem * poczatek, int dana) {
t_elem * nowy=tworz(dana);
nowy->nast=poczatek;
return nowy;
}
t_elem * usun_poczatek(t_elem * poczatek) {
if(poczatek == NULL)
return NULL;
t_elem * nast=poczatek->nast;
free(poczatek);
return nast;
}
typedef struct stos {
t_elem * glowa;
} t_stos;
void push(t_stos * stos, int dana) {
stos->glowa=dodaj_poczatek(stos->glowa, dana);
}
int isempty(t_stos * stos) {
if(stos->glowa == NULL) {
return 1;
}
else {
return 0;
}
}
int pop(t_stos * stos) {
if(isempty(stos))
return 0;
int dana = stos->glowa->dana;
stos->glowa=usun_poczatek(stos->glowa);
return dana;
}
int getch(void);
void ungetch(int);
/* Funkcja getop pobierajaca nastepny operator lub liczbe */
int getop(char s[])
{
int i, c;
while ((s[0] = c = getch()) == ' ' || c == '\t'); /* Pominiecie spacji */
s[1] = '\0';
if (!isdigit(c) && c != '.')
return c; /* c nie jest liczba */
i = 0;
if (isdigit(c)) /* Pobierz czesc calkowita */
while (isdigit(s[++i] = c = getch()));
if (c == '.') /* Pobierz czesc ulamkowa */
while (isdigit(s[++i] = c = getch()));
s[i] = '\0';
if (c != EOF)
ungetch(c);
return NUMBER;
}
char buf[BUFSIZE]; /* Bufor dla ungetch */
int bufp = 0; /* Nastepna wolna pozycja w buforze */
int getch(void) /* Pobiera znak */
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c) /* Wycofuje znak do strumienia danych wejsciowych */
{
if (bufp >= BUFSIZE)
printf("Blad: zbyt wiele znakow.\n");
else
buf[bufp++] = c;
}
int main()
{
t_stos * stos;
inicjuj(&stos);
printf("Kalkulator RPN\n");
printf("\n");
printf(" + -> dodawanie\n");
printf(" - -> odejmowanie\n");
printf(" * -> mnozenie\n");
printf(" / -> dzielenie\n");
printf(" = -> wyswietlenie wyniku badz gornego elementu stosu\n");
printf(" e -> sprawdzenie czy stos jest pusty \n");
printf(" p -> wyjecie 'gornego' elementu stosu, wyswietlenie go i jego usuniecie\n");
printf(" q -> zakonczenie dzialania kalkulatora\n");
printf("\n");
printf("Podaj dzialanie:\n");
int type;
int op2; /* Wprowadzenie dwoch */
int op3; /* pomocniczych zmiennych */
char s[MAXOP];
while ((type =getop(s)) != EOF)
{
switch (type)
{
case NUMBER:
push(stos, atof(s));
break;
case '+':
push(stos, pop(stos) + pop (stos));
break;
case '*':
push (stos, pop(stos) * pop(stos));
break;
case '-':
op2 = pop(stos);
push(stos, pop(stos) - op2);
break;
case '/':
op2 = pop(stos);
if(op2 != 0.0)
push(stos, pop(stos) / op2);
else
printf("Blad: proba dzielenia przez 0.\n");
break;
case '=':
op3 = pop(stos);
printf("%d", op3);
push(stos, op3);
break;
case 'e':
op3 = pop(stos);
if(op3 == 0.0)
{
printf("Stos jest pusty.\n");
}
else
{
printf("Stos nie jest pusty.\n");
}
push(stos, op3);
break;
case 'q':
exit(0);
break;
case 'p':
printf("%d", pop(stos));
break;
case '\n':
break;
default:
printf("Blad: nieznana operacja.\n");
break;
}
}
return 0;
}