1 / 5
Jun 2018

Witam,
mam problem na który natknąłem sie podczas robienia zadania ze zbioru: https://pl.spoj.com/problems/GLUTTON/2
Problem polega na tym, że kod ( kod - https://pastebin.com/nHEXdyPx6)
odpalony w Visual Studio(tak, pamiętam o dołączeniu #include “stdafx.h”) dla pierwszego zestawu danych zwraca taki output: “-43160200”.
Z ciekawości wrzuciłem go do Codeblocksa, gdzie zwrócił poprawne wartości, a sam kod ZAAKCEPTOWAŁ JUŻ SĘDZIA, ale chciałbym uniknąć tego problemu w przyszłości i dowiedzieć się dlaczego w ogóle występuje. Proszę o pomoc!

PS*. Mógłby mi ktoś również wyjaśnić, dlaczego VS wyrzuca mi błąd przy każdej próbie zamknięcia dynamicznej tablicy “delete [] tablica”? Nie spotkałem sie do tej pory z tym problemem w CB.

  • created

    Jun '18
  • last reply

    Jun '18
  • 4

    replies

  • 904

    views

  • 3

    users

  • 4

    links

Jeśli chcesz aby Twój kod działał jednakowo w różnych kompilatorach, musisz trzymać się specyfikacji języka, inaczej możesz trafiać na tego typu niespodzianki. W Twoim przypadku problem powodują linie:

float *suma = new float[proby];
//...
suma[i] += floor(86400.0 / czasy[j]);

Przy deklarowaniu tablicy dynamicznej nie masz gwarancji, że wszystkie jej elementy zostaną wyzerowane. VS rezerwuje dla Ciebie po prostu fragment pamięci wraz ze wszystkim co tam akurat jest. Musisz ręcznie iterować po takiej tablicy i ustawić 0. W gcc/codeblock ten sam problem też może wystąpić przy większych tablicach.

Ja go nie używam do zadań na spoju. Służy on do przyśpieszenie budowy projektu, składającego się z wielu plików, a tutaj mamy zawsze jeden plik. We właściwościach projektu możesz to wyłączyć:

Co do:

 system("pause");

lepiej jest stawiać breakpoint’a na return 0, bo prawdopodobnie i tak odpalasz program w debugu. Nie trzeba pamiętać, żeby to potem usunąć.

Nie wyrzuca, a przynajmniej nie u mnie. Zmieniłem Twój kod na taki:

i program w VS kończy się bezbłędnie.

Co do wspomnianych wyżej linijek z sumą - nie byłem świadom, że VS zatrzymuje wartości w pamięci, a co do zamykania tablicy - spróbowałem ponownie i już wszystko działa jak powinno, zapewne coś namieszałem w kodzie. Ponownie dziękuje Ci @j4rooo za pomoc.

Czyli chyba raczej dalej nie jesteś świadom. Bo nie chodzi tu zupełnie o kompilator, tylko o specyfikę języka C/C++. Jeżeli używasz fragmentu pamięci, jak tu, do sumowania, czy do zliczania, to ty jako programista musisz zapewnić, że ten fragment zostanie wcześniej przygotowany - wyzerowany. W przeciwnym razie używasz tej pamięci i czasami będzie ona zawierała zero[a] a czasami nie - będzie zawierała jakieś wartości-śmieci i wtedy katastrofa - twój program da nieprawidłowy wynik. Zależy to więc tak naprawdę bardziej od prawdopodobieństwa [ilości testów] a nie kompilatora czy środowiska jako takiego. Możliwe, że dodatkowo CB przy uruchamianiu, czyści sobie piaskownice, a VS nie i dlatego takie braki [nie zerowanie kluczowych zmiennych] szybciej się ujawnia w VS. To samo dzieje się na spoju, czy ideone.com, błąd może ujawnić się, dopiero przy którymś kolejnym uruchomieniu.

PS
Powinieneś wyszukać wątków do tego zadania i poczytać je. A także zaSTANOWIĆ SIĘ I ODPOWIEDZIEĆ [sorry caps lock] po co Ci są tu potrzebne tablice.,

W zasadzie to miałem na myśli, taki, ot skrót myślowy, dziękuje za uwagi. :smiley:
PS. Spojrzałem na kod jeszcze raz, poczytałem, może rzeczywiście te wszyystkiie tablice nie były potrzebne i można było ogarniczyć się do jednej.