programowanieProgramista C

Wyjaśnij różnicę między stosem a stertą w języku C i kiedy lepiej używać danego typu pamięci?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

W języku C pamięć dla zmiennych może być przydzielana albo w stosie (stack), albo w stercie (heap).

  • Stos — przydziela pamięć automatycznie przy wejściu do funkcji i zwalnia ją przy wyjściu. Szybko, ale objętość pamięci jest ograniczona rozmiarem stosu (zazwyczaj kilka MB).
  • Sterta — przydziela pamięć dynamicznie przez malloc, calloc, realloc i zwalnia ją ręcznie przez free. Objętość pamięci jest ograniczona możliwościami systemu, ale dostęp jest wolniejszy, a zwolnienie pamięci kontrolowane ręcznie.

Kiedy używać stosu:

  • Dla zmiennych lokalnych, jeśli ich rozmiar jest mały i znany na etapie kompilacji.
  • Dla argumentów funkcji i małych tablic.

Kiedy używać sterty:

  • Kiedy rozmiar pamięci jest wcześniej nieznany.
  • Dla dużych lub długożyjących obiektów.

Przykład kodu:

// Na stosie int arr[10]; // Na stercie int* parr = malloc(sizeof(int) * 10); // Nie zapomnij zwolnić pamięci free(parr);

Pytanie z podstępem.

Pytanie: Co się stanie, jeśli do tablicy przydzielonej przez malloc nie wywoła się funkcji free?

Odpowiedź: Dojdzie do wycieku pamięci (memory leak). Dynamicznie przydzielona pamięć nie zostanie automatycznie zwolniona, co z czasem może prowadzić do wyczerpania pamięci aplikacji lub całego systemu.

Przykład kodu:

void leak() { int* leakArr = malloc(100 * sizeof(int)); // Brak wywołania free(leakArr), pamięć jest tracona }

Historia

W pewnym projekcie programiści przydzielali pamięć dla struktury opisującej sesję użytkownika przez malloc, ale zapomnieli wywołać free po zakończeniu pracy z sesją. W efekcie projekt przez kilka dni tracił pamięć, serwer „upadał” z błędem braku pamięci. Problem został rozwiązany dopiero po profilowaniu z Valgrind i naprawieniu wszystkich pominiętych free.


Historia

Programista przydzielił dużą tablicę (do 10 MB) na stosie dla tymczasowych obliczeń. Na serwerze z małym rozmiarem stosu doprowadziło to do awarii aplikacji z błędem przekroczenia stosu. Po analizie należało przenieść bufor do sterty.


Historia

Jeden z programistów postanowił przechowywać długie ciągi w stosie, ale rozmiar ciągu był subiektywnie określany przez użytkownika. Przy wprowadzeniu bardzo długiego ciągu aplikacja się zawieszała z błędem dostępu do pamięci. Ostatecznie podjęto decyzję o przeniesieniu wprowadzonych danych do sterty z kontrolą długości.