Czasem życie zmusza do pisania w sławetnym i na szczęście zanikającym już języku C. A tam nie ma chociażby takich luksusów jak STL z niezastąpionymi pojemnikami. O wszelkie struktury danych trzeba zatroszczyć się samemu, co obejmuje także tak podstawowe jak dynamiczne tablice.
Jak wiadomo, takie tablice należy samodzielnie alokować, zmieniać ich rozmiar (z kopiowaniem zawartości) oraz zwalniać, gdy nie są już potrzebne. Najwyraźniej więc wybitnie przydatne są tu funkcje malloc
i free
, prawda? Otóż nieprawda :)
O wiele wygodniej jest bowiem używać funkcji realloc
:
Jej nazwa wskazuje, że jej głównym przeznaczeniem jest zmiana rozmiaru już zaalokowanego kawałka pamięci. Zazwyczaj sprowadza się to zresztą do przydzielenia nowego, skopiowania tam zawartości starej porcji i zwolnienia jej. Jednakże w dwóch szczególnych przypadkach realloc
zachowuje się inaczej – zależy to od parametrów, jakie jej podamy:
NULL
), funkcja przydzieli pamięć w ilości bajtów wyrażonej drugim parametrem – czyli zachowa się jak malloc
free
To sprawia, że możemy używać funkcji realloc
w postaci wywołania podobnego jak powyżej zawsze wtedy, gdy musimy zmienić rozmiar tablicy. Można na przykład dodać do niej element w taki oto sposób:
Nie musimy się martwić, czy tablica została wcześniej zaalokowana czy nie. Analogicznie wygląda usuwanie elementów z końca lub początku tablicy – wówczas nie trzeba przejmować się tym, czy z tablicy coś zostanie. Tak naprawdę opakowywanie obu tych operacji w funkcje nie jest nawet specjalnie potrzebne.
Jedynym warunkiem, aby to wszystko działało, jest odpowiednie zainicjowanie wskaźnika na tablicę oraz zmiennej przechowującej jej rozmiar – co jest aczkolwiek dość oczywiste:
I to właściwie wszystko. W sumie więc nie jest to może std::vector
, ale w C nie ma co wybrzydzać :)
Pomijając fakt, że jest to strasznie nieoptymalne rozwiązanie, to faktycznie – działa. Ale w przypadku dodawania do tablicy w pętli po jednym int, czy częsta reallokacja dużej przestrzeni pamięci jest trochę bez sensu.
Oczywiście dla większej wydajności powinno się robić tak, to robią wektory STL – czyli oprócz rozmiaru trzymać też tzw. pojemność (capacity). Pojemność jest równa liczbie elementów, na które starczy miejsca bez realokacji. Jeśli właściwy rozmiar tablicy osiągnie lub przekroczy tę pojemność, należy odpowiednio ją zwiększyć (i realokować) – zwykle dwukrotnie.