malloc()-funksjon i C-bibliotek med EKSEMPEL

⚡ Smart oppsummering

malloc() i C reserverer en minneblokk på heapen under kjøretid og returnerer en void-peker til sin første byte, slik at programmer kan be om lagring hvis størrelse er ukjent inntil koden faktisk kjøres.

  • 🧠 Kjøretidsallokering: malloc() reserverer minne under utførelse når den nødvendige størrelsen ikke er kjent ved kompileringstid.
  • 📦 Syntaks: En cast_type-peker mottar malloc(byte_size), vanligvis dimensjonert med sizeof for portabilitet.
  • ⚠️ NULL-sjekk: En mislykket forespørsel returnerer en NULL-peker, så valider resultatet før du derefererer det.
  • Pekeraritmetikk: Blokken er sammenhengende, så bruk + i stedet for ++ for å nå array-elementer.
  • 🧹 Frigjør minnet: Frigjør hver blokk med free() for å forhindre minnelekkasjer og dinglende pekere.
  • 🤖 AI-hjelp: AI-assistenter og GitHub Copilot utkaster malloc()-kall og flagger manglende free()-setninger.

malloc()-funksjon i C

Hva er malloc i C?

Malloc()-funksjonen står for minneallokering. Det er en funksjon som brukes til å tildele en minneblokk dynamisk. Den reserverer minneplass av spesifisert størrelse og returnerer null-pekeren som peker til minneplasseringen. Pekeren som returneres er vanligvis av typen void. Det betyr at vi kan tilordne malloc-funksjon til enhver peker.

Hva er malloc i C

syntax

ptr = (cast_type *) malloc (byte_size);

Her

  • ptr er en peker av cast_type.
  • Malloc-funksjonen returnerer en peker til det tildelte minnet til byte_size.
Example: ptr = (int *) malloc (50)

Når denne setningen er utført, er en minneplass på 50 byte reservert. Adressen til den første byten med reservert plass er tilordnet pekeren ptr av typen int.

Tenk på et annet eksempel på malloc-implementering:

#include <stdlib.h>
int main(){
int *ptr;
ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */
    if (ptr != NULL) {
      *(ptr + 5) = 480; /* assign 480 to sixth integer */
      printf("Value of the 6th integer is %d",*(ptr + 5));
    }
}

Utgang:

Value of the 6th integer is 480

Legg merke til at sizeof(*ptr) ble brukt i stedet for sizeof(int) for å gjøre koden mer robust når *ptr-deklarasjonen senere typecastes til en annen datatype.

Tildelingen kan mislykkes hvis minnet ikke er tilstrekkelig. I dette tilfellet returnerer den en NULL-peker. Så du bør inkludere kode for å se etter en NULL-peker.

Husk at det allokerte minnet er sammenhengende og kan behandles som en matrise. Vi kan bruke pekeren aritmetikk for å få tilgang til arrayelementene i stedet for å bruke parenteser []. Vi anbefaler å bruke + for å referere til arrayelementer fordi bruk av inkrementering ++ eller += endrer adressen som er lagret av pekeren.

Malloc-funksjonen kan også brukes med karakterdatatypen så vel som komplekse datatyper som strukturer.

Hvorfor bruke malloc() i C?

Statiske arrayer og vanlige variabler fikserer størrelsen sin når programmet kompileres, noe som kaster bort plass når kravet viser seg å være mindre og feiler fullstendig når det viser seg å være større. malloc() løser dette ved å be om minne under kjøretid, slik at et program kan dimensjonere en buffer til den nøyaktige mengden data det mottar. Denne fleksibiliteten under kjøretid er kjernen i dynamisk minnetildeling i C.

Dynamisk allokering med malloc() er det riktige valget i flere vanlige situasjoner:

  • Mengden input er ukjent før programmet kjører, for eksempel lesing av en fil eller en brukerlevert liste.
  • Store blokker er nødvendige som ville overfylt den begrensede stakken, siden malloc() henter data fra den mye større heapen.
  • Data må overleve funksjonen som opprettet dem, fordi heap-minnet vedvarer til det eksplisitt frigjøres.
  • Strukturer og arrayer må vokse eller krympe mens programmet kjører.

Fordi den reserverte blokken leveres tilbake som en peker, kan den sendes billig mellom funksjoner uten å kopiere de underliggende dataene.

Slik frigjør du minne allokert av malloc()

Minne reservert av malloc() ligger på heapen og frigjøres aldri automatisk. Når et program fortsetter å allokere uten å frigjøre, forbruker det sakte alt tilgjengelig minne, en feil kjent som en minnelekkasje. Free()-funksjonen returnerer en ferdig blokk til systemet slik at plassen kan brukes på nytt.

Free()-funksjonen tar et enkelt argument, pekeren som malloc() returnerte, og frigir hele blokken samtidig:

int *ptr;
ptr = malloc(10 * sizeof(int));
if (ptr != NULL) {
    /* use the allocated memory here */
    free(ptr);   /* release the block */
    ptr = NULL;  /* avoid a dangling pointer */
}

Følg disse reglene for å administrere dynamisk minne på en sikker måte:

  • Kall free() nøyaktig én gang for hver vellykkede malloc(); å frigjøre den samme blokken to ganger forårsaker udefinert oppførsel.
  • Sett pekeren til NULL etter frigjøring, slik at den ikke kan brukes om igjen som en dinglende peker.
  • Aldri frigjør() en peker som malloc() ikke returnerte, inkludert en som er forskjøvet av pekeraritmetikk.
  • Match hver tildeling med en samsvarende utgivelse før pekeren går utenfor rekkevidde.

keeping Balansert allokering og frigjøring er kjernedisiplinen innen manuell minnehåndtering i C, og det forhindrer både lekkasjer og krasj forårsaket av gjenbruk av frigjort minne.

malloc() vs. calloc(): Viktige forskjeller

malloc() og calloc() begge reserverer heap-minne, men de er forskjellige i argumentene sine og i hvordan de behandler den nye blokken. malloc() tar ett argument, det totale antallet byte, og lar innholdet være uinitialisert, slik at blokken inneholder uforutsigbare søppelverdier inntil programmet skriver til den. calloc() tar to argumenter, antallet elementer og størrelsen på hvert av dem, og sletter hver byte til null før pekeren returneres.

De praktiske forskjellene kommer ned til tre punkter:

  • Initialisering: calloc() nullstiller minnet, mens malloc() ikke gjør det, noe som gjør malloc() litt raskere når verdiene uansett skal overskrives.
  • Argumenter: du skriver malloc(n * size) men calloc(n, size) for å reservere samme array.
  • Brukstilfelle: velg calloc() når en ren, nullstilt blokk er viktig, og malloc() når hastighet er foretrukket og initialisering håndteres manuelt.

Begge funksjonene deklareres i stdlib.h, begge returnerer en void-peker eller NULL ved feil, og begge gir minnet tilbake med den samme free()-funksjonen.

Spørsmål og svar

I C er konverteringen valgfri og frarådes ofte, fordi void* konverterer automatisk til en hvilken som helst objektpeker, og en eksplisitt konvertering kan maskere en manglende stdlib.h include. C++, men rollebesetningen er påkrevd.

En NULL-retur betyr at forespørselen mislyktes, vanligvis på grunn av utilstrekkelig minne. Sjekk alltid pekeren før du bruker den, fordi dereferering av NULL fører til udefinert oppførsel og vanligvis krasjer programmet.

realloc() endrer størrelsen på en blokk som tidligere er reservert av malloc(), keeping eksisterende data opp til den mindre størrelsen. Hvis den feiler, returnerer den NULL og lar den opprinnelige blokken være intakt, så tilordne resultatet til en midlertidig peker først.

En minnelekkasje oppstår når heap-minne fra malloc() aldri frigjøres med free(). Programmet fortsetter å reservere plass det ikke lenger bruker, noe som gradvis kan tømme ut minnet som er tilgjengelig for det.

malloc() reserverer minne på heapen, ikke stacken. Heapblokker forblir gyldige inntil du kaller free(), slik at de kan overleve funksjonen som opprettet dem, i motsetning til automatiske stackvariabler som forsvinner ved retur.

malloc() er en bibliotekfunksjon som returnerer void* og trenger sizeof for å beregne byte. C++ new er en operator som returnerer en typepeker og kaller konstruktører. Koble malloc() med free(), og new med delete.

Ja. AI-kodingsassistenter utarbeider malloc()-kall, setter inn NULL-sjekker og flagger manglende free()-kall eller lekkasjer, og de kan forklare pekeraritmetikk. Kompiler og test alltid den genererte koden før du stoler på den.

GitHub Copilot foreslår malloc(), sizeof() og matchende free()-linjer fra en kommentar som beskriver intensjonen din. RevSe hvert forslag for manglende NULL-sjekker og lekkasjer før du kompilerer.

Oppsummer dette innlegget med: