Pamięć dynamiczna w języku C

0

Witajcie. Przychodzę z teoretycznym zapytaniem odnośnie dynamiczności w języku C. Zastanawia mnie, jak to jest ze zwalnianiem pamięci. Przejdźmy do przykładu.

#include <stdio.h>
#include <stdlib.h>
int **alokuj(void);
void dealokuj(int **tab);
int main(void){
    int **t = alokuj();
    dealokuj(t);
    return 0;
}
int **alokuj(void){
    int **tablica = (int **) malloc(5*sizeof(int*));
    for(int i=0; i<5; i++)
        tablica[i] = (int *) malloc(sizeof(int));
    return tablica;
}
void dealokuj(int **tab){
    for(int i=0; i<5; i++)
        free(tab[i]);
    free(tab);
}

Na studiach nauczono mnie, że w funkcji alokuj musimy zwrócić wartość wskaźnika do wskaźnika do tak utworzonej tablicy. Dlaczego więc, w funkcji dealokującej pamięć, takiego wskaźnika nie musimy już zwracać? Czy przypadkiem funkcja dealokująca pamięć nie powinna wyglądać następująco:

int **dealokuj(int **tab){
    for(int i=0; i<5; i++)
        free(tab[i]);
    free(tab);
  return tab;
}

a jej wywołanie:

t = dealokuj(t);

I jeszcze jedno pytanie. Dlaczego po zwolnieniu pamięci za pomocą funkcji free nadal mamy dostęp do wartości w tej tablicy? W jaki sposób radzą sobie z tym profesjonalni programiści, czy w tym przypadku należy np. wyzerować wartości w tablicy, a dopiero potem zwolnić pamięć? Czy tylko powinno się używać funkcji free, ze względu na stratę czasu podczas zmieniania wartości tablicy?

1
  1. A czemu miałbyś coś zwracać z funkcji dealokuj? Po co?
  2. Bo to od systemu operacyjnego zależy co zrobi ze zwolnioną pamięcią. Przez jakiś czas mogą być tam jeszcze poprzednie dane. Z reguły jak zwalniasz dane, to Cię nie interesuje i zostawiasz jak są i pozwalasz by system potem te dane nadpisał za ciebie jak będzie potrzeba. Rzadko jest sytuacja gdy "ręcznie" trzeba wyczyścić taki fragment pamięci przed jego zwolnieniem.
1
knifer0 napisał(a):

Na studiach nauczono mnie, że w funkcji alokuj musimy zwrócić wartość wskaźnika do wskaźnika do tak utworzonej tablicy. Dlaczego więc, w funkcji dealokującej pamięć, takiego wskaźnika nie musimy już zwracać?

Na jakich studiach uczą tak, że jeśli alokuje się miejsce na tablice to musi być podwójny wskaźnik (jeśli można wiedzieć)?

Uważasz, że poniższy zapis jest błędny?

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

int* alokuj() {
    return (int*) malloc(5*sizeof(int));
}

void dealokuj(int* tab) {
    free(tab);
}

int main() {
    int* tab = alokuj();

    printf("%d %d %d %d %d\n",  tab[0], tab[1], tab[2], tab[3], tab[4]);

    dealokuj(tab);

    return 0;
}

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