[C]Tablica z o dynamicznym rozmiarze


(Ziom32) #1

Witam.

Jednym z elementów programu, który muszę napisać jest wczytywanie liczb do tablicy aż do momentu, kiedy wpiszemy zero. Problem w tym, że rozmiar tablicy nie jest znany.

Napisałem to w taki sposób:

Jednym ze zgłaszanych błędów jest:

"This may be due to a corruption of the heap."

Jeśli ktoś widzi co zrobiłem źle, proszę o jakieś wskazówki.

Z góry dzięki.


(Drobok) #2

Jak pobierasz wartości to je zapisuj. Zwiększanie wskaźnika o 1 to nonsens. Tut do c i ciupaj. Będziesz miał konkretny problem to spytaj.


(Xwars) #3

Na początek zdecyduj się czy we wskaźniku "tablica" trzymasz początek tablicy czy jej koniec bo w tej chwili używasz go do obu celów. Ponadto

sizeof(*tablica)

z pewnością nie jest tym co chciałes osiągnąć, na komputerach 64bitowych zwróci 8(rozmiar wskaźnika) podczas gdy pojedynczy int w tablicy zajmie tylko 4.


(Ryan) #4

Tam jest operator wyłuskania, na obu zwróci 4, bo to nie rozmiar wskaźnika, a elementu tablicy:

sizeof(int) == sizeof(long) == 4

Co do samego programu - więcej w nim błędów niż linii kodu. Zacznijmy od początku.

  1. Kod umieszczamy w tagach [code] a nie [quote]

    include

    include

    /* Program wczytuje liczby do tablicy za każdym razem zwiększając jej rozmiar, aż do napotkania zera*/

    void main()

    {

    int a,rozm,i=0;
    
    int *tablica;
    
    printf("Podaj następny element: ");
    
    tablica = (int *) malloc(sizeof *tablica);
    
    scanf("%d",&a);
    
    while(a!=0)
    
    {
    
    	(*tablica)=a;
    
    	tablica = (int *) realloc(tablica, i*sizeof(*tablica) + sizeof(*tablica));
    
    	tablica+=1;
    
    	i++;
    
    	printf("Podaj następny element: ");
    
        scanf("%d",&a);
    
    }

    }

  2. Dobrze jest inicjalizować zmienne przy tworzeniu, szczególnie wskaźniki.

    int *tablica = NULL;

  3. Ta linijka nie ma najmniejszego sensu:

    tablica = (int *) malloc(sizeof *tablica);

  4. Powtarzanie operacji wejścia w kodzie to kiepski pomysł, szczególnie jeśli każda kopia ma robić mniej więcej to samo:

    printf("Podaj następny element: ");

    tablica = (int *) malloc(sizeof *tablica);

    scanf("%d",&a);

oraz

printf("Podaj następny element: ");

scanf("%d",&a);
  1. Tracisz wskaźnik do początku alokowanego obszaru...

    tablica+=1;

...więc realloc nie wie jaki blok próbujesz powiększyć.

tablica = (int *) realloc(tablica, i*sizeof(*tablica) + sizeof(*tablica));
  1. Ta linijka nie ma sensu:

    tablica = (int ) realloc(tablica, isizeof(tablica) + sizeof(tablica));

  2. Nigdy nie zwalniasz pamięci.

  3. Definiujesz zmienną rozm i jej nie używasz.

  4. Main nie zwraca typu void, tylko int. Zawsze.

  5. Realloc co obrót pętli to paskudny wzorzec w kodzie. Pamięć jest tania. Zaalokuj sobie na przykład sto kilo i jak braknie, wtedy użyj realloc, żeby powiększyć rozmiar dwukrotnie.

  6. Naucz się na prostszym przykładzie jak działa alokacja pamięci. Najlepiej obserwując wszystko w debuggerze. Bo ewidentnie nie wiesz co robisz.


(Xwars) #5

Oho, chyba za długa przerwę od C miałem :oops: