ProgrammatieBackend C developer

Vertel in detail over het toewijzen, gebruiken en correct vrijgeven van dynamisch geheugen in C via malloc/free. Welke valkuilen zijn er bij het werken met dynamisch geheugen?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

Geschiedenis van de kwestie:

Mechanismen voor dynamische geheugenallocatie verschenen in C met de functies van de standaardbibliotheek malloc/free in <stdlib.h>. Ze maakten de implementatie van variabele-grootte structuren, complexe verzamelingen en objecten mogelijk, wat een sterke impuls gaf aan de ontwikkeling van de taal en het gebruik ervan in grootschalige programmering.

Probleem:

Werken met dynamisch geheugen vereist volledige controle van de programmeur over de levenscyclus van objecten. Fouten (geheugenlekken, dubbele vrijgave, onjuist gebruik van pointers) kunnen leiden tot crashes of kwetsbaarheden (bijvoorbeeld exploits door gebruik na vrijgave).

Oplossing:

— Controleer altijd de geretourneerde waarden van malloc/calloc/realloc. Als de toewijzing mislukt, retourneren ze NULL. — Bij het vrijgeven van geheugen moet de pointer naar NULL worden ingesteld om gebruik van de vrijgegeven blok te voorkomen. — Gebruik de pointer niet na free. — Zorg voor correcte koppeling tussen malloc/free en calloc/free.

Voorbeeldcode:

#include <stdio.h> #include <stdlib.h> int main() { int *arr = malloc(5 * sizeof(int)); if (!arr) { perror("Kon geheugen niet toewijzen"); return 1; } for (int i = 0; i < 5; ++i) arr[i] = i * i; for (int i = 0; i < 5; ++i) printf("%d ", arr[i]); printf(" "); free(arr); arr = NULL; return 0; }

Belangrijke kenmerken:

  • malloc/calloc/realloc retourneert void*, vereist expliciete type-conversie (niet voor C, wel voor C++).
  • Na free wordt de pointer ongeldig.
  • De grootte van het toegewezen geheugen wordt altijd beïnvloed door het type en het aantal elementen (n * sizeof(type)).

Vragen met een val.

Wat gebeurt er als je geheugen dat met malloc is toegewezen, probeert te vrijgeven met de delete-operator of omgekeerd (in C++)?

Je kunt de mechanismen voor toewijzing en vrijgave van geheugen tussen talen (C/C++) niet mengen. In C — alleen malloc/free, in C++ — new/delete.

Wat gebeurt er als je probeert free(NULL) aan te roepen?

free(NULL) is veilig (dit is gegarandeerd door de C-standaard). Zo'n aanroep doet niets.

Kun je realloc gebruiken om een geheugenblok te vergroten of te verkleinen en wat gebeurt er met de originele pointer?

realloc kan het geheugenblok verplaatsen, en als dat gebeurt, wordt de oude pointer ongeldig. Ken altijd de nieuwe pointer toe:

ptr = realloc(ptr, new_size);

Typische fouten en anti-patronen

  • Gebruik van geheugen na free (gebruik na vrijgave).
  • Dubbele aanroep van free voor dezelfde pointer.
  • Geheugenlekken (toegewezen, maar niet vrijgegeven).
  • Fouten in de berekening van de grootte van het geheugen bij malloc (vergeten sizeof(...)).
  • Negeer de retourwaarde NULL bij onsuccesvolle malloc.

Voorbeeld uit het leven

Negatieve casus

Geheugen toegewezen voor een array in een lus, maar vergeten vrij te geven aan het einde van de iteratie. 'S Nachts heeft het programma op de server al het RAM verbruikt.

Voordelen:

  • De code is eenvoudiger, minder controles.

Nadelen:

  • Geheugenlek, lagere prestaties, applicatiecrash.

Positieve casus

In de lus hebben we altijd geheugen vrijgegeven na gebruik, alle controles op NULL werden onmiddellijk na malloc uitgevoerd, we gebruikten debugging-tools om op geheugenlekken te letten.

Voordelen:

  • Stabiele werking, geen lekken.
  • Code is gemakkelijk te onderhouden en uit te breiden.

Nadelen:

  • Iets omvangrijkere code, vereist nauwkeurigheid in elke fase van de levenscyclus van het geheugen.