Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

malloc, calloc - jak poprawnie alokować pamięć dla tablicy

Goofy1991 18 Dec 2011 13:55 2706 4
  • #1
    Goofy1991
    Level 11  
    Siemanko, chciałbym zrozumieć funkcję malloc i calloc, proszę o pomoc.

    w przykładzie użyję calloc, oto składnia:
    Code: c
    Log in, to see the code


    Otóż, chcę przydzielić pamięć dla dwuwymiarowej tablicy.
    Jej wymiary wczytuję poprzez argv, są to int x; i int y;
    Kod który mnie interesuje to:

    Code: c
    Log in, to see the code


    czyli w tym momencie calloc powinien zwrócić do **array adres pod którym mogę coś zapisywać w ten sposób:
    Code: c
    Log in, to see the code

    oczywiście przy założeniu, że jest odpowiednio duża ta tablica.

    Jak już wspominałem, program przydziela x i y za pomocą argv (na razie przez proste atoi) i teraz: jeśli zadane wymiary tablicy są np. 5x5 2x2 to wszystko działa,
    Problem pojawia się gdy chcę zrobić tablicę np. 5x1, 5x2 wtedy gdy chcę całą tablicę wypełnić przez rand(); pojawiają się segfaulty.
    Co innego przy tablicach 5x5 3x3 5x10, wszystko działa dobrze.
    Dlaczego nie mogę zrobić tablicy

    oto cały od jeśli się przyda, program odpalamy ./a.out x y, gdzie x i y to jakieś inty nieduże

    Code: c
    Log in, to see the code


    ponadto wszelkie uwagi co do kodu mile widziane, przypominam że to jest wersja "robocza" ;)
  • #2
    beluosus
    Level 25  
    Pierwszy błąd przy alokacji, musisz podać rozmiar wskaźnika, a nie typu (chociaż w tym wypadku prawdopodobnie na jedno wychodzi).
    Code: c
    Log in, to see the code

    Wszystko rozchodzi się o to, że mylisz szerokość z wysokością tablicy. Zapełnianie tablicy powinieneś zrobić w taki sposób (zamienione x z y ewentualnie b z a w array[a][b]):
    Code: c
    Log in, to see the code

    Na podstawie tego z resztą powinieneś sobie poradzić analogicznie.
    Skoro na początku i tak wypełniasz tablicę to skorzystaj z malloc, nowy blok pamięci nie jest inicjalizowany zerami.
    Pierwszy argument main powinien być typu całkowitego (int argc).
    W instrukcji warunkowej korzystasz z operatora bitowego | zamiast logicznego ||. Poza tym powinieneś sprawdzać ilość argumentów (argc) - te porównania z NULLami są kompletnie bezsensowne i nie powinny działać gdy podasz za małą liczbę parametrów.
    Na display_array() nie chce mi się już patrzeć. ;)
  • #3
    marcin2500
    Level 12  
    błąd jest prosty - zrozumiałeś trochę źle idee tablic wielowymiarowych. Tablica dwuwymiarowa to jest zwykła tablica jednowymiarowa, która przechowuje w sobie inna tablicę wielowymiarową.

    Poprawiony kod
    int **array = (int**) calloc(x, sizeof(int*)); //powinno być sizeof(int*) bo pierwsza tablica będzie odpowiedzialna za wiersze - przechowywać będzie tablicę jednowymiarową intów czyli int*
    int i;
    for(i=0;i<x;i++) //źle indeksowałeś. Nie do y a do x, bo pierwszy wymiar mówi o wierszach
    array[i] = (int*) calloc(y, sizeof(int));


    Brakowało Ci również rzutowania do odpowiedniego typu bo malloc i calloc zwracają void*. Ponadto w tym programie powinieneś raczej używać malloca bo jest szybszy (Calloc to jest malloc + "zerowanie zawartości pamięci").


    Kolejny duży błąd to brak zwalniania pamięci - używając malloca i calloca musisz na koniec programu albo kiedy jest Ci już nie potrzebna zaalokowana pamięć zwolnić ją - polecenie "free".
  • #4
    PDT
    Level 24  
    Witam,

    Poniższy fragment kodu ilustruje stosowaną przeze mnie metodę tworzenia dynamicznych tablic wielowymiarowych, głównie 2-wymiarowych. Przydzielam je jako JEDEN spójny obszar pamięci, dobrze jest je zorganizować wierszami ze względu na zgodność ze statycznymi tablicami w tj.
    double A[8][8];
    double *B = (double *)malloc(8*8*sizeof(double))
    były identycznie uporządkowane wierszami (jak w dołączonym kodzie).
    Używam malloc a nie calloc ponieważ i tak po utworzeniu trzeba obszar wypełnić danymi więc calloc nie musi go zerować.

    Code: c
    Log in, to see the code


    Prosty przydział i zwalnianie pamięci, brak zabaw z wektorami wskaźników pośrednich.

    Powodzenia
  • #5
    Goofy1991
    Level 11  
    Jsna sprawa chłopaki ! dzięki, bardzo przyjemnie się pisało, już rozumiem te malloc'i :)