C Naruszenie ochrony pamięci

0

Cześć,
mam problem z programem odwzorowującym działanie automatu skończonego. Pokrótce mówiąc, jako znaki do taśmy (wektora) program ma pobierać wartości z *argv[]. Kompiluje się bez problemu, jednak przy próbie uruchomienia wyświetla się błąd - naruszenie ochrony pamięci (core dumped). Nie wiem, co robię źle, próbowałem różnych kombinacji, niestety bez skutku, dlatego zdecydowałem się poprosić Was o pomoc. Poniżej kod, za wszelkie rady z góry dziękuję :). Jeśli coś jest niejasne - pytajcie.

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


int main (int argc, char *argv[])
{
  char q0 = '1';
  char q1 = '2';
  char q2 = '3';
  char q3 = '4';
  char stan = q0;
  char tasma[argc - 1];
  int i, n;

  for (n = 1; n <= argc; ++n)    /*Pobiera do tasmy wartosci z *argv[] */
  {
    tasma[n - 1] = atoi(argv[n]);
  }

  for (i = 0; i <= argc; ++i)
    {
      switch (stan)
        {
        case '1':
          switch (tasma[i])
            {
            case '0':
              stan = q1;
              printf(" -> q1");
              break;
            case '1':
              stan = q2;
              printf(" -> q2");
              break;
            }
        case '2':
          switch (tasma[i])
            {
            case '0':
              stan = q3;
              printf(" -> q3");
              break;
            case '1': 
		   stan = q1;
              printf(" -> q1");
              break;
            }
        case '3':
          switch (tasma[i])
            {
            case '0':
              stan = q0;
              printf(" -> q0");
              break;
            case '1':
              stan = q3;
              printf(" -> q3");
              break;
            }
        case '4':
          switch (tasma[i])
            {
            case '0':
              stan = q1;
              printf(" -> q1");
              break;
            case '1':
              stan = q2;
              printf(" -> q2");
              break;
            }
        }

      switch (stan)
        {
        case '1':
          printf ("\nStan koncowy to q0\n");

        case '2':
          printf ("\nStan koncowy to q1\n");

        case '3':
          printf ("\nStan koncowy to q2. Ciag zostal zaakceptowany.\n");

        case '4':
 		printf ("\nStan koncowy to q3\n");
        }



      return 0;
    }
} 
0

Sypie się przy uruchomieniu bez parametrów czy zawsze?

2
for (n = 1; n <= argc; ++n)    /*Pobiera do tasmy wartosci z *argv[] */

Wychodzisz poza zakres tablicy.

0

No i nie masz zabezpieczenia przed wywołaniem bez parametrów. Tzn. program zachowa się bezsensownie przy takim uruchomieniu.

0

Sypie się bez względu na obecność argumentów.
Poprawiłem pętlę oraz dodałem zabezpieczenie na wypadek uruchomienia bez argumentów:

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


int main (int argc, char *argv[])
{
  char q0 = '1';
  char q1 = '2';
  char q2 = '3';
  char q3 = '4';
  char stan = q0;
  char tasma[argc - 1];
  int i, n;

  argc > 1 ? : fprintf(stderr, "%s: Brak argumentow wywolania\n", argv[0]);

  for (n = 1; n <= argc; ++n)    /*Pobiera do tasmy wartosci z *argv[] */
  {
    tasma[n - 1] = atoi(argv[n]);
  }

  for (i = 0; i <= argc - 1; ++i)

 

Jednak nie rozwiązuje to problemu, błąd jak był, tak jest :/

0

Przecież wstawiłeś dokładnie taką samą pętle. Rozumiesz co miałem na myśli mówiąc, że wychodzisz poza zakres tablicy? Ta druga pętla również jest skopana.

argc > 1 ? : fprintf(stderr, "%s: Brak argumentow wywolania\n", argv[0]);;

wtf? Zwykłe ify stały się już zbyt mainstreamowe?

char tasma[argc - 1];

Do obsługi czegoś takiego jest potrzebne odpowiednie rozszerzenie, które nie wchodzi w standard języka, więc lepiej nie używać.</del>

Znajdź (w tym wypadku) największa liczbę, która spełnia warunek pętli i zastanów się, czy element w tablicy o takim indeksie istnieje. Pamiętaj o numerowaniu od zera.

0

@ly000 Wchodzi, wchodzi, tyle że nie w ANSI, a C99.
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
Strona 114 (rozdz. 6.7.5)

1

Może lepiej to tak zorganizować:

#include <stdio.h>
#include <stdlib.h>
 
enum State { q0, q1, q2, q3 };
struct Auto { enum State from; char sign; enum State to; } automat[]=
  {
     { q0,'0',q1 }, { q0,'1',q2 },
     { q1,'0',q3 }, { q1,'1',q1 },
     { q2,'0',q0 }, { q2,'1',q3 },
     { q3,'0',q1 }, { q3,'1',q2 },
  };
 
int main(int argc,char *argv[])
  {
   enum State st;
   int p,sign;
   unsigned i,k;
   if(argc<2) exit(fprintf(stderr,"podaj jako parametry sprawdzane słowa\n"));
   for(p=1;p<argc;++p)
     {
      printf("Slowo \"%s\": ",argv[p]);
      for(st=q0,i=0;(sign=argv[p][i])!='\0';++i)
        {
         for(k=0;(k<sizeof(automat)/sizeof(*automat))&&((automat[k].from!=st)||(automat[k].sign!=sign));++k) {}
         if(k>=sizeof(automat)/sizeof(*automat)) exit(fprintf(stderr,"nieznany znak alfabetu %c \n",sign));         
         st=automat[k].to;
        }
      printf("Stan koncowy to q%d.%s\n",st,st==2?" Ciag zostal zaakceptowany.":"");
     }
   return 0;
  }

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