Nieznane źródło błędu - SIGSEGV

0

Czy moglibyście sprawdzić, co tu jest przyczyną błędu (powodem są polecenia po ostatnim tekście między /**/). Dzięki.

 
#include <iostream>
#include <list>
using namespace std;
int main() {
        int lmiast, ldrog;
        cin >> lmiast;
        cin >> ldrog;
        int lpowiazan=0, zmiasta, domiasta, x, y;
        int ttwod[(lmiast+1)][(lmiast+1)];
        x=0;
        y=0;
        while (!(x==(lmiast+1)))
                {
                y=0;
                while (!(y==(lmiast+1)))
                        {
                        ttwod[x][y]=0;
                        y=y+1;
                        }
                x=x+1;  
                } 
                x=(0);
        for (x=0; (!(x==ldrog)); x=x+1)
                {
                cin >> zmiasta;
                cin >> domiasta;
                ttwod[zmiasta][domiasta]=(ttwod[zmiasta][domiasta]+1);
                }
/* KONIEC TABLICY. CO DALEJ? */
        /* WYPISANIE TYCH, KTÓRE ŁĄCZĄ SIĘ Z 2 */
        x=0;
        list<int>listawarstw;
        while (!(x==lmiast))
                {
                if (!(ttwod[x][2]==0))
                        {
                        listawarstw.push_back(x);
                        }
                if (ttwod[1][2]!=0)
                        {
                        listawarstw.pop_back();
                        lpowiazan=lpowiazan+1;
                        }       
                x=x+1;  
                }
                x=0;
                y=0;
                cout<<listawarstw.size()<<endl;
/*DODAWANIE KOLEJNYCH WARSTW, SPRAWDZANIE CZY ŁĄCZĄ SIĘ Z 1*/
        int warstwowanie=0;
        do
                {
                x=listawarstw.back();
                while (y!=lmiast-1)
                        {
                        if (ttwod[y][x]!=0)
                                {
                                if (y==1)
                                        {
                                        lpowiazan=lpowiazan+1;
                                        }
                                if (y!=1)
                                        {
                                        listawarstw.push_front(y);
                                        }
                                }
                        y=y+1;
                        }
                listawarstw.pop_back();
                warstwowanie=warstwowanie+1;
                }
        while (warstwowanie!=ldrog || listawarstw.size()>0);
        cout<<lpowiazan;
        cout<<listawarstw.size();
}
0

Debugger ukradli?

0

Jaki debugger? Przepraszam, jeżeli zadaję pytania, które nie zasługują na Waszą uwagę, ale jeżeli nie mogę sobie z czymś poradzić, to proszę o pomoc. W c++ programuję od niecałych dwóch tygodni, więc nie ze wszystkim potrafię sobie poradzić. O jaki debugger chodzi?

0

Może trochę rozjaśni: http://pl.wikipedia.org/wiki/Debugger
Tym razem mogę podebugować za ciebie, tylko podaj jakieś przykładowe dane dla których się wywala.

PS Zerknąłbym do kodu, ale jest mało czytelny. Popracuj też nad tym.

0

Dzięki. Wywala m.in. dla

6 7 
1 3 
1 4 
3 2 
4 2 
5 6 
6 5 
3 4
 

Dlaczego jest mało czytelny? Tabulacje robię chyba w dobrych miejscach?

Dodałbym do poprzedniego, ale się nie zalogowałem: jaki debugger mógłbyś polecić na linuksa, jaki na windowsa, a jaki na androida (jeżeli jakiś jest)? Dużo ich na wiki :)

0

Wywala się tutaj: listawarstw.pop_back();

Co do czytelności to za dużo niepotrzebnych nawiasów. Wcięcia też trochę dziwne. Mało czytelne pętle. Nadużywanie x=x+1 zamiast x++ itp

Jeżeli chodzi o debugger to ja używam gdb

0

Dzięki. Chyba wiem co trzeba zrobić. Jak będę miał dostęp do komputera, to sprawdzę, czy zadziała :)

0

Wersja poprawiona:

#include <iostream>
#include <list>
#include <cstring>
using namespace std;
int main() 
{
    int lmiast, ldrog;
    cin >> lmiast;
    cin >> ldrog;
    int lpowiazan=0, zmiasta, domiasta;    
    int ttwod[lmiast][lmiast]; //to powinno byc alokowane na stercie, ale juz nie bede mieszal
 
    memset(ttwod, 0, lmiast*lmiast*sizeof(int));
 
    for (int i=0; i<ldrog; i++)
    {
        cin >> zmiasta;
        cin >> domiasta;
        ttwod[zmiasta][domiasta]++;
    }
    /* KONIEC TABLICY. CO DALEJ? */
    /* WYPISANIE TYCH, KTÓRE ŁĄCZĄ SIĘ Z 2 */
    list<int> listawarstw;
    for(int i=0; i<lmiast; i++)
    {
        if (ttwod[i][2]!=0)
            listawarstw.push_back(i);

        if (ttwod[1][2]!=0)
        {
            listawarstw.pop_back();
            lpowiazan++;
        }
    }

    cout<<listawarstw.size()<<endl;
    /*DODAWANIE KOLEJNYCH WARSTW, SPRAWDZANIE CZY ŁĄCZĄ SIĘ Z 1*/
    for(int warstwowanie=0; warstwowanie<ldrog && listawarstw.size()>0; warstwowanie++)
    {
        int i=listawarstw.back();
        for(int j=0; j<lmiast; j++)
        {
            if (ttwod[j][i]!=0)
            {
                if (j==1)
                    lpowiazan++;
                else
                    listawarstw.push_front(j);
            }
        }
        listawarstw.pop_back();
    }
 
    cout<<lpowiazan<<endl;
    cout<<listawarstw.size()<<endl;
 
}

Nie wywala się, ale nie wiem czy wyjście jest poprawne, bo nie widziałem zadania.

0

autor:

Źle wcinasz kod. Zamiast:

bleble (cośtam)
    {
    kolejne instrukcje;
    }

Powinieneś zrobić:

bleble (cośtam)
{
    kolejne instrukcje;
}

Albo (ja tak robię):

bleble (cośtam) {
    kolejne instrukcje;
}
0

Dodam tutaj zarzuty do czytelności kodu. Po pierwsze nazwy większości zmiennych nic nie mówią (co robi zmienna x). Dodatkowo zmienne powinny być deklarowane jak najbliżej użycia. Nie powinno się też używać tych samych zmiennych, gdy zmienia się ich przeznaczenie (co robi zmienna x w danym bloku). Jak robisz warunki, to lepiej stosować if (x==1) {...} else {...} niż if (x==1){...} if (x!=1){...}.

@Wibowit: tego stylu także się używa, choć jest mniej popularny (ze względu na to, że jest brzydszy), ale konsekwentnie stosowany nie jest błędem. Inna sprawa jest, gdy kod wygląda tak:

 int main(int,char**){
  if (0){
     zrobCos()
        }
                     }

Formatowanie kodu ma pokazać strukturę kodu, więc w tym miejscu styl używany przez merlinnot nie jest zły, bo spełnia to zadanie.

Jeszcze jedno. Na listach w C++ nie powinno się używać size() w celu sprawdzenia, czy nie jest pusta, ponieważ ta operacja może być O(n), a nie O(1) jak empty() (tak jest na przykład zrobione w domyślnym STLu GCC).

0

Dobra, teraz to wygląda tak:

#include <iostream>
#include <list>
#include <cstring>
using namespace std;
int main() 
{
    int lmiast, ldrog;
    cin >> lmiast;
    cin >> ldrog;
    int lpowiazan=0, zmiasta, domiasta;    
    int ttwod[lmiast][lmiast]; //to powinno byc alokowane na stercie, ale juz nie bede mieszal
 
    memset(ttwod, 0, lmiast*lmiast*sizeof(int));
 
    for (int i=0; i<ldrog; i++)
    {
        cin >> zmiasta;
        cin >> domiasta;
        ttwod[zmiasta][domiasta]++;
    }
    /* KONIEC TABLICY. CO DALEJ? */
    /* WYPISANIE TYCH, KTÓRE ŁĄCZĄ SIĘ Z 2 */
    list<int> listawarstw;
    for(int i=0; i<lmiast; i++)
    {
        if (ttwod[i][2]!=0)
            listawarstw.push_back(i);
 
        if (ttwod[1][2]!=0)
        {
            listawarstw.pop_back();
            lpowiazan++;
        }
    }
    /*DODAWANIE KOLEJNYCH WARSTW, SPRAWDZANIE CZY ŁĄCZĄ SIĘ Z 1*/
    for(int warstwowanie=0; warstwowanie<ldrog && listawarstw.size()>0; warstwowanie++)
    {
        int i=listawarstw.back();
        for(int j=0; j<lmiast; j++)
        {
            if (ttwod[j][i]!=0)
            {
                if (j==1)
                    lpowiazan++;
                else
                    listawarstw.push_front(j);
            }
        }
        if (listawarstw.size()==0)
        	break;
        listawarstw.pop_back();
    }
 
    cout<<lpowiazan<<endl;
 
}
 

Działa, wyjście jest dobre (3). Po co jest

 #include <cstring>

? I co oznacza alokowane na stercie, czy to poważny błąd? Czy przyspieszy działanie programu?

PS. Treść zadania:

 

Problem statement
A bicycle race is being organized in a land far, far away. There are N towns in the land, numbered 1 through N. There are also M one-way roads between the towns. The race will start in town 1 and end in town 2.
How many different ways can the route be set? Two routes are considered different if they do not use the exact same sequence of roads.

Input
The first line of input contains two integers N and M (1 ≤ N ≤ 10 000, 1 ≤ M ≤ 100 000), the number of towns and roads.
Each of the next M lines contains two different integers A and B, representing a road between towns A and B.
Towns may be connected by more than one road.

Output
Output on a single line the number of distinct routes that can be set. If that number has more than nine digits, output only the last nine digits of the number. If there are infinitely many routes, output "inf" (quotes for clarity).
0

W tym nagłówku jest zdefiniowana funkcja memset.
http://pl.wikibooks.org/wiki/C/Wskaźniki#Dynamiczna_alokacja_pami.C4.99ci i http://pl.wikibooks.org/wiki/C%2B%2B/Zarządzanie_pamięcią Tak jak teraz jest źle bo jeżeli wartość lmiast będzie za duża to program się wyłoży.

0

lmiast to max 10000, to chyba nie tak dużo? (chyba, że dużo :))
Dla tamtego wejścia działa, ale dla tego niestety nie:

 
31 60
1 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
20 21
21 22
22 23
23 24
24 25
25 26
26 27
27 28
28 29
29 30
30 31
31 2
1 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
17 18
18 19
19 20
20 21
21 22
22 23
23 24
24 25
25 26
26 27
27 28
28 29
29 30
30 31
31 2

Nie jest takie skomplikowane, program kompiluje się i wykonuje, ale wynik to 0, a powinno być 73741824. Próbowałem dla mniejszego, analogicznego przykładu, ale wynik taki sam:

8 7
1 3
3 4
4 5
5 6
6 7
7 8
8 2 

Dodam jeszcze link do ideone: https://ideone.com/aez7M

0
int lpowiazan

Typintnie pomieści Ci tak dużych wartości jak 73741824. Użyj long int lub long long int.

http://pl.wikipedia.org/wiki/Liczba_ca%C5%82kowita_(typ_danych)

0

To mi się bardzo nie podoba, przemyśl:

         if (ttwod[1][2]!=0)
        {
            listawarstw.pop_back();
            lpowiazan++;
        }

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