Counting Sort problem

0

Witam
Zakodziłem w C algorytm counting sort i niby działa tylko jeśli próbuje wywołać program dla danych o większych wartościach to się zawiesza. Może ktos wie co jest tutaj nie tak?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


int i,n,b,*tab_we,*tab_wy,*tab_pom;

int main()
{
    double czas;
    clock_t start,end;
    scanf("%d",&n);
    tab_we=malloc(n*sizeof(*tab_we));
    tab_wy=malloc(n*sizeof(*tab_wy));
    for (i=1;i<=n;i++)
    {
        scanf("%d",&tab_we[i]);
        if (b<tab_we[i]) b=tab_we[i];
    }
    tab_pom=malloc(b*sizeof(*tab_pom));
    for (i=1;i<=b;i++) tab_pom[i]=0;


    //Sortowanie
    start=clock();
    for (i=1;i<=n;i++) tab_pom[tab_we[i]]++;
    for (i=2;i<=b;i++) tab_pom[i]+=tab_pom[i-1];
    for (i=n;i>=1;i--)
    {
        tab_wy[tab_pom[tab_we[i]]]=tab_we[i];
        tab_pom[tab_we[i]]--;
    }
    end=clock();
    //Koniec sortowania

    czas=(end-start)/(double)CLK_TCK;
    printf("%f\n",czas);
    if (n<11)
    {
        for (i=1;i<=n;i++) printf("%d, ",tab_we[i]);
        printf("\n");
        for (i=1;i<=n;i++) printf("%d, ",tab_wy[i]);
    }
    free(*tab_we);
    free(*tab_wy);
    free(tab_pom);
    return 0;
}





0

Pierwszy bląd jest tutaj:

    tab_we=malloc(n*sizeof(*tab_we));
    tab_wy=malloc(n*sizeof(*tab_wy));

bo zdajesz sobie sprawę że wywołanie *tab_we to już jest odwołanie sie do nieswojej pamięci i moze spowodować segfault? Rozumiem że napisanie sizeof(int) bylo za mało hakerskie?
Następny bląad to pętle od 1 do n zamiast od 0 do n-1 i w efekcie błąd "off-by-one" i kolejny potencjalny segfault.
Potem znów pętla od n zamiast od n-1 i kolejny segfault.
A na koniec niepoprawne wywołanie free() bo argumentem powinien być wskaźnik (więc nie powinno tam być dereferencji).
W zasadzie mało która linijka w tym kodzie jest napisana poprawnie...

0

A mógłbyś napisac jak powinna wyglądać linijka z malloc'iem ? Z góry dzięki

0
Shalom napisał(a)

Pierwszy bląd jest tutaj:
bo zdajesz sobie sprawę że wywołanie *tab_we to już jest odwołanie sie do nieswojej pamięci i moze spowodować segfault? Rozumiem że napisanie sizeof(int) bylo za mało hakerskie?
co?! Przecież sizeof to nie jest funkcja! Akurat taki styl jest uznawany za mniej podatny na błędy.

0

Wiem ze sizeof jest operatorem rozwijanym w czasie kompilacji, ale mimo wszystko moim zdaniem wstawianie w kodzie gdziekolwiek dereferencji niezainicjalizowanego wskaźnika jest w złym guście. Mniej podatne na błędy? Faktycznie mniejsza szansa że ktoś poda zły rozmiar tablicy przypadkiem jakby typ się zmienił, ale mnie to mimo wszystko wygląda dość słabo i ryzykownie.
Zresztą tym bardziej ze autor wyraźnie ma pewne problemy ze wskaźnikami (biorąc pod uwagę wywołanie free czy błędy off-by-one)

0

#twoja pętla idzie po indeksach od 1 do n zamiast od 0 do n-1 ! Co grozi błędami (w najlepszym razie segfault-em)
#kompilator się nie pluje, ze używasz niezainicjowanej wartości b?
#popatrz do wiki tam jest przykładowy kod i opisane ograniczenia algorytmu.

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