funkcja free()

0

Mam taki kod

    int m, n;
    double **tab;
    printf("Podaj ilosc wierszy");
    scanf("%d", &m);
    printf("Podaj ilosc kolumn");
    scanf("%d", &n);
    tab = (double**) malloc(sizeof (double*) * m);
    for (int i = 0; i < m; i++){
        tab[i] = (double*) malloc(sizeof (double)*n);
    }
   char temp = getchar();
    temp = getchar();
    temp = getchar();
    for (int i = 0; i < m; i++){
        free(tab[i]);
    }
    free(tab);
    printf("\nzwolniono");
    temp = getchar();
    temp = getchar();

Mam włączony menedżer zadań i obserwuje jak pamięć się zachowuje.
W momencie zaalokowania pamięci wykres zauważalnie podnosi się i utrzymuje stały poziom.
Po przejściu do następnego etapu, czyli do zwalniania pamięci wykres nie opada.
Dopiero po zakończeniu pracy programu, wykres wraca co normy.
Dlaczego wykres pamięci nie opada po zastosowaniu funkcji free()?

2

Ponieważ ze względów wydajnościowych nie każda alokacja i dealokacja wiąże się z wysyłaniem zapytań do systemu operacyjnego. Najwyraźniej Twoja biblioteka standardowa jest zoptymalizowana pod kątem ponownych alokacji (wywołanie syscalla jest relatywnie drogie).

0

nie każda alokacja i dealokacja wiąże się z wysyłaniem zapytań do systemu operacyjnego

Czy mógłbyś to zdanie rozwinąć, bo nie wiem o co chodzi z tym wysyłaniem zapytań do systemu operacyjnego?

Czyli pamięć została zwolniona w chwili wykonania funkcji free() czy dopiero jest zwalniana w chwili ponownej alokacji?

Zrobiłem test i zadeklarowałem drugą takiej samej wielkości tablicę po funkcji free() i ono już nie poruszyła wykresem. To znaczy, że pamięć dopiero wtedy została zwolniona i ponownie zaalokwana czy że już była wcześniej zwolniona tylko nie było tego widać na wykresie?

4

To znaczy, że alokacje są wielopoziomowe. Na wymyślonym przykładzie:

Alokujesz 8 bajtów. Czyli malloc(8). Ponieważ system nie trzyma pamięci w blokach mniejszych niż 4096 bajtów, alokacja 8 bajtów jest niemożliwa. Można oczywiście za każdym razem zwrócić stronę, ale to bezsens. Dlatego też biblioteka standardowa wykonuje taką operację, a potem pamięta, że ma dostępny taki blok pamięci. Przy następnej alokacji, nie pyta systemu, tylko przydziela kolejną pamięć z tego bloku co już ma. Jak wywołasz free() to nie zwalnia bezpośrednio, tylko zaznacza sobie że ma wolną pamięć. Strategii alokacji jest multum (są o tym książki), nie ma żadnej "optymalnej" dla każdego przypadku, więc trzeba przewidywać najprawdopodobniejszy przypadek. Tutaj biblioteka może zwolnić taką stronę jak zobaczy, że cała jest pusta, a może zostawić ją sobie na przyszłe alokacje.

W Twoim przypadku sobie zostawiła. Nie masz nad tym za wielkiej kontroli jeśli chcesz korzystać z domyślnych narzędzi. Ale prawdą jest też, że rzadko jest Ci taka kontrola potrzebna.

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