• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Program został zatrzymany

VPS Starter Arubacloud
0 głosów
344 wizyt
pytanie zadane 11 sierpnia 2016 w C i C++ przez LordOfTheStrings Obywatel (1,610 p.)
edycja 11 sierpnia 2016 przez LordOfTheStrings

Program debuguje i kompiluje się poprawnie, ale po uruchomieniu go wyskakuje okienko z komunikatem, że program został zatrzymany. Kod:


#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int n, m ,przycisk, maksimum, minimum;
    cin >> n >> m;
    int liczniki[1000000];

    for(int i=0; i<m; i++)
    {
        cin >> przycisk;

        if(przycisk==n+1)
        {
            minimum=maksimum;
        }

        else
        {
            liczniki[przycisk-1] = max(minimum, liczniki[przycisk-1]);
            liczniki[przycisk-1]++;
            max(liczniki[przycisk-1], maksimum);
        }
    }

    for(int i=0; i<n; i++)
    {
        cout << max(minimum, liczniki[i]);
    }
    return 0;
}

W czym może tkwić problem? Z góry dziękuję za wszelką pomoc.

4 odpowiedzi

+1 głos
odpowiedź 11 sierpnia 2016 przez Pijany Python Użytkownik (900 p.)
wybrane 11 sierpnia 2016 przez LordOfTheStrings
 
Najlepsza
Stack overflow. Próbujesz stworzyć za dużą tablicę. Alokuj pamięć dynamicznie albo użyj vector'a.
komentarz 11 sierpnia 2016 przez LordOfTheStrings Obywatel (1,610 p.)
Dziękuję, w tym tkwił problem.
+2 głosów
odpowiedź 11 sierpnia 2016 przez obl Maniak (51,280 p.)

Używasz zmiennych maksimum i minimum bez ich inicjalizacji. Zastanawiam się też jaki to:

            minimum=maksimum;

ma sens, jeżeli tym zmiennym nie przypisałeś wcześniej żadnej wartości. Domyślnie zmienne te przechowują śmieci, które znajdowały się w pamięci komputera, a tymi śmieciami może być dowolna liczba (w tym przypadku całkowita).

Albo to:

max(liczniki[przycisk-1], maksimum);

Próbujesz określić maksymalną liczbę ale wyniku ani nie wyświetlasz, ani nie zapisujesz nigdzie.

Co stanie się, jak do zmiennej przycisk podasz wartość mniejszą od 1 lub większą od 1000000.

Piszesz, że masz jakiś komunikat, a następnie program się zamyka, to podaj treść tego komunikatu, bo być może jest on związany właśnie z próbą odwołania się do pamięci, do której nie powinieneś mieć dostępu.

1
komentarz 11 sierpnia 2016 przez LordOfTheStrings Obywatel (1,610 p.)
Poprawiłem błędy i odpowiedziałem na pana pytania w sąsiednim poście. Nie jestem pewien czy nie powinienem tego zrobić w komentarzu, ale dopiero teraz zauważyłem, że posty są sortowane według liczby głosów.
+2 głosów
odpowiedź 11 sierpnia 2016 przez LordOfTheStrings Obywatel (1,610 p.)
edycja 11 sierpnia 2016 przez LordOfTheStrings

Poprawiłem błędy, podane przez użytkownika obl. Jako osoba niedoświadczona założyłem, że przyjmują one domyślnie wartość 0. Tablicę też powinienem początkowo zapełnić zerami?

Ta linijka:

max(liczniki[przycisk-1], maksimum);

to tylko wynik mojego gapiostwa i tego, że pierwszy raz korzystałem z funkcji max/min.

Oto poprawiony kod:

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int n, m ,przycisk, maksimum{0}, minimum{0};
    cin >> n >> m;
    int liczniki[1000000];

    for(int i=0; i<m; i++)
    {
        cin >> przycisk;

        if(przycisk==n+1)
        {
            minimum=maksimum;
        }

        else
        {
            liczniki[przycisk-1] = max(minimum, liczniki[przycisk-1]);
            liczniki[przycisk-1]++;
            maksimum = max(liczniki[przycisk-1], maksimum);
        }
    }

    for(int i=0; i<n; i++)
    {
        cout << max(minimum, liczniki[i]) <<" ";
    }
    return 0;
}

W zadaniu miałem sprecyzowane dane wejściowe, stąd ten zakres.

Treść zadania brzmi mniej więcej tak:

Tomek znalazł zabawkę, która ma n+1 przycisków. Nad każdym, poza ostatnim znajduję się licznik, początkowo wyzerowany. Naciskając dowolny z n przycisków wartość na licznik nad tym przyciskiem zwiększa się o 1. Natomiast przycisk n+1 sprawia, że wszystkie liczniki pokazują największą wartość z dotychczas pokazanych. Wiemy, które przyciski wciskał kolejno Tomek, a chcemy znać wartości liczników po zakończeniu zabawy.

Wejście:

Dwie liczby całkowite: n i m (1<=n, m<=1000000)

W drugim wierszu m  liczb całkowitych oznaczających kolejne wciskane przez Tomka przyciski

Wyjście:

n liczb całkowitych oznaczających wartości kolejnych przycisków, po zakończeniu zabawy.

Przykład:

Wejście:

5 7

3 4 4 6 1 4 4

Wyjście:

3 2 2 4 2

Zadanie jest autorstwa pana Jacka Tomasiewicza.

Komunikat o błędzie wygląda zwyczajnie. Nie wiem czy uda się coś z niego odczytać:

 

komentarz 11 sierpnia 2016 przez jpacanowski VIP (101,940 p.)
int n, m ,przycisk, maksimum = 0, minimum = 0;

maksimum i minimum to nie tablice.

komentarz 11 sierpnia 2016 przez LordOfTheStrings Obywatel (1,610 p.)
Standard C++11 pozwala na stosowanie inicjalizatora klamrowego bez znaku przypisania "=" dla pojedynczych wartości. Taka ciekawostka.
1
komentarz 11 sierpnia 2016 przez draghan VIP (106,230 p.)

jpacanowski, nic nie szkodzi, że to nie tablice. Od C++11 taka inicjalizacja jest poprawna.

LordOfTheStrings - a jak z SO? Próbowałeś utworzyć tę tablicę na stercie?

1
komentarz 11 sierpnia 2016 przez LordOfTheStrings Obywatel (1,610 p.)

Problemem było właśnie SO. Już udało mi się to naprawić. Dziękuję :)

0 głosów
odpowiedź 11 sierpnia 2016 przez LordOfTheStrings Obywatel (1,610 p.)
edycja 11 sierpnia 2016 przez LordOfTheStrings

Teza użytkownika Pijany Python okazała się prawdziwa. Wystarczyła dynamiczna alokacja pamięci.

Działający kod wygląda tak:

#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    int n, m ,przycisk, maksimum{0}, minimum{0};
    cin >> n >> m;
    int * liczniki = new int[m];

    for(int i=0; i<m; i++)
    {
        liczniki[i]=0;
    }

    for(int i=0; i<m; i++)
    {
        cin >> przycisk;

        if(przycisk==n+1)
        {
            minimum=maksimum;
        }

        else
        {
            liczniki[przycisk-1] = max(minimum, liczniki[przycisk-1]);
            liczniki[przycisk-1]++;
            maksimum = max(liczniki[przycisk-1], maksimum);
        }
    }

    for(int i=0; i<n; i++)
    {
        cout << max(minimum, liczniki[i]) <<" ";
    }

    delete[] liczniki;

    return 0;
}

 

Bardzo dziękuję wszystkim, którzy udzielili się w tym wątku.

2
komentarz 11 sierpnia 2016 przez draghan VIP (106,230 p.)

A gdzie delete[]? :<

1
komentarz 11 sierpnia 2016 przez LordOfTheStrings Obywatel (1,610 p.)
Poprawione
komentarz 11 sierpnia 2016 przez Pijany Python Użytkownik (900 p.)
W tym przypadku to nie problem. delete i tak znalazło by się przed return, więc wychodzi na to samo jak system sam zwalnia pamięć przed zabiciem procesu.
1
komentarz 11 sierpnia 2016 przez draghan VIP (106,230 p.)
Chyba się zbyt dużo naczytałeś moich komentarzy, Pijany Python. ;) Owszem, zwalnia pamięć.

Ale wypada po sobie posprzątać, nawet jeśli sprzątaczki czekają za drzwiami. :)
komentarz 12 sierpnia 2016 przez Pijany Python Użytkownik (900 p.)
Masz rację że sprzątanie po sobie jest dobrym nawykiem, ale zwróciłem tylko uwage, że w tym programie nie ma znaczenia czy wywołamy delete czy nie. Btw. nie rozumiem o co Ci chodzi w pierwszym zdaniu.
komentarz 12 sierpnia 2016 przez draghan VIP (106,230 p.)
Też kilka razy zwracałem na to uwagę na tym Forum, jednak po zastanowieniu uznałem, że nie powinienem był tego robić. Młodzi programiści mają brzydki zwyczaj szybkiego przyswajania brzydkich zwyczajów.

Podobne pytania

0 głosów
3 odpowiedzi 213 wizyt
0 głosów
1 odpowiedź 146 wizyt
pytanie zadane 15 stycznia 2020 w C i C++ przez xZenit Użytkownik (760 p.)
–1 głos
0 odpowiedzi 145 wizyt

92,452 zapytań

141,261 odpowiedzi

319,074 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...