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

Średnia Arytmetyczna: SPOJ - błąd wykonania (SIGSEGV)

Object Storage Arubacloud
0 głosów
333 wizyt
pytanie zadane 22 sierpnia 2017 w C i C++ przez Kamil Paradowski Użytkownik (620 p.)

Witam, oto mój kod do zadania z tytułu zadania z serwisu SPOJ: 

#include <iostream>

int main()
{
    short t, n, number[n], closest;
    float sum=0, comparison, difference;
    std::cin>>t;
    for(int i=0;i<t;i++)
    {
        std::cin>>n;
        for(int i=0;i<n;i++)
        {
            std::cin>>number[i];
            sum+=number[i];
        }
        closest=number[0];
        if (sum/n-number[0]<0)
            difference=((sum/n-number[0])-2*(sum/n-number[0]));
        else if (sum/n-number[0]>0)
            difference=sum/n-number[0];
        for(int i=1;i<n;i++)
        {
            comparison=(sum/n-number[i]);
            if (comparison<0)
                comparison=((sum/n-number[i])-2*(sum/n-number[i]));
            if (comparison<difference)
            {
                difference=comparison;
                closest=number[i];
            }
        }
        std::cout<<closest<<std::endl;
        sum=0;
    }
    return 0;
}

Oto treść zadania: http://pl.spoj.com/problems/PP0604A/

Tak jak w tytule postu: Wywala mi błąd SIGSEGV, jednak nie wiem z jakiego dokładnie powodu. Poza tym wydaje mi się, że kod działa prawidłowo, sprawdzałem dla różnych testów już, ale nie mam tej 100% pewności dopóki SPOJ mi tego nie zaakceptuje. Proszę o pomoc i powiedzenie dlaczego taki błąd występuje

Pozdrawiam!

komentarz 22 sierpnia 2017 przez vector Dyskutant (9,200 p.)

Może to Ci pomoże

2.cpp:13:31: runtime error: index 12 out of bounds for type 'short int [*]'
2.cpp:14:26: runtime error: index 11 out of bounds for type 'short int [*]'
2.cpp:14:26: runtime error: index 11 out of bounds for type 'short int [*]'
2.cpp:14:26: runtime error: index 11 out of bounds for type 'short int [*]'
2.cpp:23:39: runtime error: index 11 out of bounds for type 'short int [*]'
2.cpp:25:64: runtime error: index 18 out of bounds for type 'short int [*]'
2.cpp:29:33: runtime error: index 33 out of bounds for type 'short int [*]'

 

komentarz 22 sierpnia 2017 przez Kamil Paradowski Użytkownik (620 p.)
edycja 22 sierpnia 2017 przez Kamil Paradowski

Zmieniłem typ zmiennej na int i działa, jednak czy mógłbyś mi wytłumaczyć skąd ten błąd? Przecież short jest w stanie pomieścić liczby dla możliwych danych z tego zadania.

Mam też błąd kiedy chce to skompliować w Code::Blocksie, nawet jak już zmieniłem na int: Przed kursorem jest liczba 255

2 odpowiedzi

+1 głos
odpowiedź 22 sierpnia 2017 przez JAKUBW Nałogowiec (33,470 p.)

1. Na początku deklarujesz zmienną n, ale nie przypisujesz jej wartości. Następnie z niej korzystasz tworząc tablicę elementową. Zawsze przed odczytem zmiennej przypisz jej wartość. Na przykład:

short n = 0;

W pamięci RAM mogą być różne rzeczy pozostawione przez inne programy i zmienna n może mieć różne wartości.

2. Tworzenie tablicy o ilości n elementów gdzie n nie jest stałe w taki sposób nie jest prawidłowe:

short n = 5;
int tab[n];

Użyj dynamicznej tablicy:

short n = 5;
const int* wsk = new int[n];
//... Rób coś
delete wsk;

 

komentarz 22 sierpnia 2017 przez vector Dyskutant (9,200 p.)

Ręczne używanie operatora new nie jest najlepszym rozwiązaniem od c++14 ponieważ c++ od tego standardu oferuje mechanizmy pozwalające na zaprzestanie użycia ręcznego zwalniania pamięci które generuje dość dużo błędów. W c++14 można napisać to tak

short n = 5;
auto tab = std::make_unique<int[]>(n);
// ...

 

komentarz 23 sierpnia 2017 przez Kamil Paradowski Użytkownik (620 p.)
Dzięki za wyjaśnienie!
+1 głos
odpowiedź 22 sierpnia 2017 przez vector Dyskutant (9,200 p.)
short t, n, number[n], closest;

short number[n]; powoduje zadeklarowanie tablicy o wielkości n, ale zaraz przecież n nie ma zdefiniowanej wartości! Skoro n nie ma zdefiniowanej wartości i nie jest zmienną globalną to w zmiennej n znajdują się jakieś śmieci, czyli dostajesz tablicę o nie wiadomo jakiej liczbie elementów.

Zagadka dlaczego zmieniłeś short na inty to nagle zadziałało. Odpowiedź jest dość prosta. Tablica number będzie używana w zakresie indeksów 0-100 więc aby short, który ma 4 bajty wielkości był większy od 100 to pierwszy bajt musi być większy od 100 lub któreś z kolejnych trzech musi być większe od 0. Typ int analogicznie z tą różnicą, że on ma 8 bajtów więc masz dużo większą szansę trafienia wartości większej od 100. Dlatego od razu zadziałało na incie. Po jakimś czasie spamowania poprzedniego rozwiązania również byś trafił.

Poprawnym sposobem byłoby zadeklarowanie tablicy nie na n elementów tylko na 100 czy tam 101.

Teraz ciekawostka, deklarowanie w taki sposób tablic nie jest w standardzie c++, jest to tylko rozszerzenie kompilatora. Możesz się samemu przekonać o tym kompilując z flagą -pedantic co spowoduje ostrzeżeniem.

2.cpp:4:22: warning: ISO C++ forbids variable length array ‘number’ [-Wvla]
  short t, n, number[n], closest;

 

komentarz 23 sierpnia 2017 przez Kamil Paradowski Użytkownik (620 p.)
Dzięki za naprawdę ciekawą i merytoryczną odpowiedź!

Podobne pytania

0 głosów
1 odpowiedź 522 wizyt
0 głosów
1 odpowiedź 1,021 wizyt
pytanie zadane 7 sierpnia 2018 w SPOJ przez Piotr Błaszczak Bywalec (2,890 p.)
+1 głos
1 odpowiedź 489 wizyt
pytanie zadane 29 czerwca 2018 w C i C++ przez ernest52 Początkujący (450 p.)

92,555 zapytań

141,403 odpowiedzi

319,560 komentarzy

61,940 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...