1 / 15
Mar 2020

Mam problem z zadaniem sort 1, w code blocks zadanie kompiluje się i dla testowych danych wejściowych zwraca poprawne wyjście, niestety po uruchomieniu sędziego wyświetla się komunikat SIGSEGV, czy ktoś może mi pomóc z rozwiązaniem tego problemu?
Oto mój kod:https://ideone.com/VrASCO14

  • created

    Mar '20
  • last reply

    Dec '21
  • 14

    replies

  • 1.0k

    views

  • 5

    users

  • 6

    likes

  • 3

    links

Na ideone masz wyraźny komunikat:

 stderr 
free(): invalid pointer

W swoim kodzie nie masz takiej funkcji, ale w takim razie dotyczy ona delete []
Powinieneś jako parametru użyć początek

Reszta jest milczeniem, a także no comments :wink:

narbej,
dziękuję za podpowiedź, po jednej korekcie sędzia zaakceptował rozwiązanie.

Trzy razy zacząłem czytać Twój kod i trzy razy przerwałem. Jak dla mnie jest on bardzo zagmatwany, nazwy nic nie ułatwiają. Ok. nazwy funkcji wypisz, wczytaj, sortuj są jasne, ale przyznaję nie mam pojęcia co robi funkcja zamień, sorry nie chciało mi się w to wgłębiać.
Moja rada jest taka (nie wiem czy bardziej doświadczeni się z tym zgodzą):
Na początek zrób to zadanie korzystając ze zwykłą struktury, bez alokacji pamięci, w ogóle bez wskaźników. Gdy to Ci dobrze zadziała możesz strukturę zamienić klasą, próbować alokować pamięć. I ważna rzecz jeśli oczekujesz by ktoś Ci pomógł - Twój kod musi być czytelniejszy, możesz (powinieneś?) to wspierać komentarzami (chociaż też nie jest dobrze tu popaść w przesadę, lepiej gdy nazwy zmiennych i funkcji są czytelne). Nawiasem mówiąc nie bardzo rozumiem dlaczego funkcję sortuj umieściłeś wewnątrz klasy.

Dodałbym zamianę funkcji zapamietaj w konstruktor i c-stringów w std::string.

Gratulacje, ale musisz sobie zdać sprawę, że AC wcale nie świadczy o jakości kodu. Jak najbardziej przyznaję rację @korkirw a błąd znalazłem bez czytania i bez zbytniego zagłębiania się w twój kod.

Sędzia zaakceptował rozwiązanie? To niedobrze.
Niedobrze dla Ciebie, bo zostałeś z zadaniem zaliczonym, ale według mnie nie bardzo można powiedzieć by było rozwiązane (chyba, ze zależy Ci tylko na uzyskaniu punktu). Nie piszę tego ze złośliwości, sam niektóre swoje zadania przerabiałem i niektóre jeszcze przerobię.

Nie chodzi mi tylko o zaliczenie zadania przez sędziego, w tym zadaniu chciałem przećwiczyć czy dobrze rozumiem mechanikę ruchu wskaźnika (wszystkie testy które robiłem działały dobrze, dlaczego mam poprawiać coś co działa?), komentarzy nie dałem przepraszam powinienem to zrobić. Hipcia dziękuję za radę funkcja zapamiętaj jest już konstruktorem a c-stringi zostały zastąpione stringami.

Jeżeli jakość mojego kodu jest słaba to proszę o podpowiedzi na co mam zwrócić uwagę żeby pisać lepiej w przyszłości (jak patrzę na swój program wcale nie wydaje mi się on zagmatwany według mnie wszystko jest logiczne dlatego nie rozumiem wypowiedzi Pana Korkirw).

Po pierwsze nie przepraszaj, najważniejsze, że to Ty jesteś z kodu zadowolony i że go rozumiesz.
To, że dla nas mógłby być bardziej czytelny to inna bajka, ale nie jesteśmy od tego by na siłę uczyć i zwracać uwagę na naszym [moim] zdaniem błedy. Wybacz, szkoda mi trochę mojego czasu.

A takich tylko zupełnie luźnych kilka moich uwag:
Lepiej jest stosować najnowszy dostępny kompilator - tutaj na spoju jest to i tak już trochę stary dobry C++14. Na stringi zmieniłeś ok. Gdyby to były “prawdziwe” metody klasy, to zrobiłbym je prywatne: sortuj i zamien. Nigdy [nie mów nigdy] float zawsze double. Unikaj i nie używaj skrótów, Ty wiesz co on oznacza ale nikt inny, co to za nazwa przeciw! - przeciwprostokątna - jeżeli już to lepiej odleglość. Są zmienne globalne i lokalne - ale jeżeli używasz klasy to chyba wiesz o tym i domyślasz się co myślę o globalnych. Zamiast tablicyPunktów [tabpunk] użyłbym vectora a wtedy ani new ani delete nie są potrzebne. W końcu to C++ a nie C. Czemu i po co tak robisz nie wiem, nie chcę wiedzieć i nie analizuję:

 if(i<=n-2)
        {
        tabpunk ++;
        }

Podobnie z funkcją zamień - jest dla mnie za zawiła, ja użyłbym gotowych funkcji z STL [swap, no i oczywiście …]. Tak, twoja funkcja sortowanie wygląda ładnie, ale nie analizuje. … :wink: Jeszcze by się coś tam znalazło, dziwne wczytywanie, nie tylko zpowodu wyżej załączonego fragmenciku kodu. Brak konstruktora i destruktora, ale to już @hipcia zauważył. I jeszcze Jeśli zaczynasz, przeczytaj koniecznie! <--kliknij w to proszę! Dokleja się do istniejącego wątku a nie tworzy nowego. Komentarze nie są konieczne - wystarczy czytelny kod i czytelne nazwy zmiennych, funkcji i klas a wtedy komentarze są wręcz zbędne.

Funkcje sortuj i zamien nie powinny być składowymi klasy Punkt, bo nie są w żaden sposób związane z obiektem je wywołującym. Warto myśleć o klasach jak o przepisach na “żyjące” obiekty. Powyższą sytuację można by przedstawić tak: Pralka może mieć funkcje wirowanie(), płukanie(), ale już niekoniecznie sortujPralkiGdzieśWOdległymWejherowie().

Dodałbym jeszcze polepszenie formatowania kodu.

Jak widzisz bardziej doświadczeni SPOJ-owicze wyjaśnili znacznie lepiej niż ja bym to zrobił. Ja bym dodał jeszcze może jedną rzecz, taką kosmetyczną. Masz dużo pustych linii co wydłuża i tak bardzo już długi kod.
Mam jeszcze jedną uwagę, nie wiem jak się na to zapatrują inni użytkownicy, zwłaszcza ci starsi (stażem, bo podejrzewam, że wiekiem to jest niewielu starszych… :slight_smile: ).
Ja wychodzę z założenia, że na takim portalu, wszyscy jesteśmy na ty, ja się w ten sposób zwracam do innych i nie oczekuję by się do mnie zwracano per “pan”, preferuję formę “ty”. Gdybyś był moim studentem to, przynajmniej w ramach zajęć, nie bardzo by mi to odpowiadało, ale tutaj myślę, że jest właściwe.

Oczywiście zgadzam się, dlatego napisałem: gdyby były “prawdziwe”. Niektórzy wrzucają wszystko do jednej klasy jak do worka, aby np pozbyć się zmiennych globalnych itp i wydaje się im, że tworzą dobry obiektowy kod. Czy tutaj tak jest? Częściowo tak, ze względu na te dwie funkcje.

ok chociaż ja jestem już w najwyższej grupie ryzyka :wink:

===

Co do polepszenia kodu, to jeszcze pare uwag:
zamiast:

 if(i<=n-2)
        {
        tabpunk ++;
        }

Ja napisałbym tak:

 if (i <= n - 2) {
        ...
        ++tabpunk;
        }

a gdy jest tylko jedna instrukcja to bez nawiasów:

  if (..) 
         ++tabpunk;

podobnie nie:

cout << (2 + (4 * 5))  << endl;

tylko

cout << 2 + 4 * 5 << '\n';

@michalkol3, w jednym miejscu masz:

int c, d;

i właśnie tak bym to pisał wszędzie, np:

int x, y;

W zadaniach na spoju, autor często używa konkretnych oznaczę, np t, n itd
Więc można użyć takich samych i bez konieczności komentowania.
n, m - ilości
x, y, z, - wiadomo
i, j, k - np indeksy/liczniki pętli
a, b, c - w zależności od treści
pkt.x, pkt[2].z itd

Pierwsza [najważniejsza zasada/prawo inżynierii] jeżeli coś działa to nie kombinuj i nie poprawiaj - zostaw w spokoju, nie eksperymentuj na “żywym ciele”

Ale Ty ani nie jesteś chyba jeszcze ani inżynierem, ani twój kod nie jest krytycznym programem systemowym. Dopiero się uczysz i tu na spoju masz okazję nie tylko “zaliczać” na AC, ale i próbować, eksperymentować, zmieniać, bawić się swoim kodem i się uczyć.

PS
nie wiem co wcisnąłem powyżej - ale …

W takim razie, gdy jednak chcę to zadanie zrobić z klasą, to jak podejść?
Ja gdybym był mniej leniwy, użyłbym:
klasa punkt
klasa zbiorpunktow <-- gdzie składowa jest kontener klasy punkt.
A że jestem, skorzystałem z STL.

PS 2
Zamiast sprawdzać czy:

sqrt ( x1² + y1² )  >/< sqrt   ( x2² + y2² )

po podniesieniu obu stron do kwadratu wystarczy:

 x1² + y1²   >/< x2² + y2² 

Zamiast sortować contener obiektów, można posortować tylko tablicę [lub kontener] wskaźników do obiektów, bez fizycznego kopiowania samych obiektów.
Jeżeli potraktujemy nasz zbiór punktów jako małą bazę danych, to pamiętanie w niej odległości [lub sumy kwadratów] jest informacją nadmiarową [redudendną] i nie potrzebną. Można tą wartość obliczać na bierząco w momencie porównywania punktów i nie koniecznie będzie to wolniejsza metoda.

1 year later

https://ideone.com/K4TL0z6
Cześć, potrzebuję pomocy fachowców. Przy ręcznym klikaniu, między innymi w PyCharmie działa na wszystkich przykładach które tutaj znalazłem, ale w Spoju (chyba) i na Ideone nie mogę przejść przez tą pustą linię na wejściu przez co zwraca błąd. Jak przez to przejść? Próbowałem dodać pusty input na koniec iteracji testu, ale nie pomaga. Z góry dziękuję za pomoc, za ewentualną nieczytelność kodu z góry przepraszam.

To nie jest pierdułka. Gdybyś ręcznie doklikiwał pustą linijkę -sam enter to też by Ci działało?
Albo użytkownik zamiast liczby wpisze tekst lub wciśnie enter? Należy sprawdzać co zostało wczytane lub przygotować się na błędy - blok try.
Tu masz łatwiej, bo wiadomo dokładnie co dostajesz.
Do swojego testu na ideone dodaj na końcu pustą linię i w tym przypadku wystarczy to co próbowałeś. I na ideone i na spoju