malloc() Funcția în biblioteca C cu EXAMPLE

⚡ Rezumat inteligent

malloc() în C rezervă un bloc de memorie pe heap în timpul execuției și returnează un pointer void către primul său octet, permițând programelor să solicite spațiu de stocare a cărui dimensiune este necunoscută până la executarea efectivă a codului.

  • 🧠 Alocare timp de execuție: malloc() rezervă memorie în timpul execuției atunci când dimensiunea necesară nu este cunoscută la momentul compilării.
  • 📦 Sintaxă: Un pointer cast_type primește malloc(byte_size), de obicei dimensionat cu sizeof pentru portabilitate.
  • ⚠️ Verificare NULL: O cerere eșuată returnează un pointer NULL, așadar validați rezultatul înainte de a-l dereferenția.
  • Aritmetica pointerilor: Blocul este contiguu, așa că folosiți + în loc de ++ pentru a accesa elementele tabloului.
  • 🧹 Eliberează memoria: Eliberați fiecare bloc cu free() pentru a preveni pierderile de memorie și pointerii care atârnă.
  • 🤖 Asistență AI: Asistenții AI și GitHub Copilot redactează apeluri malloc() și semnalează instrucțiunile free() lipsă.

Funcția malloc() în C

Ce este malloc în C?

Funcția malloc() reprezintă alocare de memorie. Este o funcție care este utilizată pentru a aloca dinamic un bloc de memorie. Rezervă spațiu de memorie de dimensiunea specificată și returnează pointerul nul care indică locația de memorie. Indicatorul returnat este de obicei de tip void. Înseamnă că putem atribui funcția malloc oricărui pointer.

Ce este malloc în C

Sintaxă

ptr = (cast_type *) malloc (byte_size);

Aici,

  • ptr este un pointer de tip_cast.
  • Funcția malloc returnează un pointer către memoria alocată pentru byte_size.
Example: ptr = (int *) malloc (50)

Când această instrucțiune este executată cu succes, un spațiu de memorie de 50 de octeți este rezervat. Adresa primului octet al spațiului rezervat este atribuită pointerului ptr de tip int.

Luați în considerare un alt exemplu de implementare malloc:

#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));
    }
}

ieșire:

Value of the 6th integer is 480

Observați că s-a folosit sizeof(*ptr) în loc de sizeof(int) pentru a face codul mai robust atunci când declarația *ptr este convertită ulterior la un tip de date diferit.

Alocarea poate eșua dacă memoria nu este suficientă. În acest caz, returnează un pointer NULL. Deci, ar trebui să includeți cod pentru a verifica dacă există un pointer NULL.

Rețineți că memoria alocată este contiguă și poate fi tratată ca o matrice. Putem folosi indicatorul aritmetic pentru a accesa elementele tabloului în loc să folosiți paranteze []. Vă recomandăm să folosiți + pentru a vă referi la elementele tabloului, deoarece utilizarea incrementării ++ sau += modifică adresa stocată de pointer.

Funcția Malloc poate fi utilizată și cu tipul de date caracter, precum și cu tipuri de date complexe, cum ar fi structurile.

De ce se folosește malloc() în C?

Tablourile statice și variabilele ordinare își fixează dimensiunea atunci când programul este compilat, ceea ce irosește spațiu atunci când cerința devine mai mică și eșuează complet atunci când devine mai mare. malloc() rezolvă această problemă prin solicitarea de memorie la momentul execuției, astfel încât un program poate dimensiona un buffer la cantitatea exactă de date pe care o primește. Această flexibilitate la momentul execuției este esența... alocarea memoriei dinamice în C.

Alocarea dinamică cu malloc() este alegerea potrivită în câteva situații comune:

  • Cantitatea de date de intrare este necunoscută până la rularea programului, cum ar fi citirea unui fișier sau a unei liste furnizate de utilizator.
  • Sunt necesare blocuri mari care ar depăși stiva limitată, deoarece malloc() extrage informații din heap-ul mult mai mare.
  • Datele trebuie să supraviețuiască funcției care le-a creat, deoarece memoria heap persistă până când este eliberată în mod explicit.
  • Structurile și tablourile trebuie să crească sau să se micșoreze în timp ce programul se execută.

Deoarece blocul rezervat este returnat ca pointer, acesta poate fi transmis între funcții cu ușurință, fără a copia datele subiacente.

Cum se eliberează memoria alocată prin malloc()

Memoria rezervată de malloc() se află în heap și nu este niciodată eliberată automat. Când un program continuă să aloce fără a elibera, consumă lent toată memoria disponibilă, un defect cunoscut sub numele de scurgere de memorie. Funcția free() returnează un bloc finalizat sistemului, astfel încât spațiul să poată fi reutilizat.

Funcția free() primește un singur argument, pointerul returnat de malloc(), și eliberează întregul bloc dintr-o dată:

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 */
}

Urmați aceste reguli pentru a gestiona memoria dinamică în siguranță:

  • Apelează free() exact o dată pentru fiecare malloc() eliberarea reușită a aceluiași bloc de două ori provoacă un comportament nedefinit.
  • Setați indicatorul la NULL după eliberare, astfel încât să nu poată fi reutilizat ca indicator suspendat.
  • Nu eliberează niciodată() un pointer pe care malloc() nu l-a returnat, inclusiv unul deplasat prin aritmetica pointerului.
  • Potrivește fiecare alocare cu o versiune corespunzătoare înainte ca indicatorul să iasă din domeniul de aplicare.

Nici unulping Alocarea și eliberarea în echilibru reprezintă disciplina de bază a gestionării manuale a memoriei în C și previne atât scurgerile de date, cât și blocajele cauzate de reutilizarea memoriei eliberate.

malloc() vs calloc(): Diferențe cheie

malloc() și calloc() ambele rezervă memorie heap, dar diferă prin argumentele lor și prin modul în care tratează noul bloc. malloc() primește un argument, numărul total de octeți, și lasă conținutul neinițializat, astfel încât blocul reține valori imprevizibile de tip gunoi până când programul scrie în el. calloc() primește două argumente, numărul de elemente și dimensiunea fiecăruia, și șterge fiecare octet la zero înainte de a returna pointerul.

Diferențele practice se reduc la trei aspecte:

  • Inițializare: calloc() aduce memoria la zero, în timp ce malloc() nu o face, ceea ce face ca malloc() să fie puțin mai rapidă atunci când valorile vor fi oricum suprascrise.
  • Argumente: scrii malloc(n * size) dar calloc(n, size) pentru a rezerva același array.
  • Caz de utilizare: alegeți calloc() când contează un bloc curat, adus la zero, și malloc() când se preferă viteza și inițializarea este gestionată manual.

Ambele funcții sunt declarate în stdlib.h, ambele returnează un pointer void sau NULL în caz de eșec și ambele își returnează memoria cu aceeași funcție free().

Întrebări frecvente

În C, conversia este opțională și adesea descurajată, deoarece void* se convertește automat la orice pointer de obiect, iar o conversie explicită poate masca o includere stdlib.h lipsă. C++, însă, distribuția este necesară.

O valoare returnată NULL înseamnă că solicitarea a eșuat, de obicei din cauza memoriei insuficiente. Verificați întotdeauna pointerul înainte de a-l utiliza, deoarece dereferențierea valorii NULL duce la un comportament nedefinit și, de obicei, provoacă blocarea programului.

realloc() redimensionează un bloc rezervat anterior de malloc(), keeping datele existente până la dimensiunea mai mică. Dacă eșuează, returnează NULL și lasă blocul original intact, așadar atribuiți mai întâi rezultatul său unui pointer temporar.

O scurgere de memorie apare atunci când memoria heap din malloc() nu este niciodată eliberată cu free(). Programul continuă să rezerve spațiu pe care nu îl mai folosește, ceea ce poate epuiza treptat memoria disponibilă.

Funcția malloc() rezervă memorie pe heap, nu pe stivă. Blocurile heap rămân valide până când apelați free(), astfel încât acestea pot supraviețui funcției care le-a creat, spre deosebire de variabilele automate ale stivei care dispar la returnare.

malloc() este o funcție de bibliotecă care returnează void* și are nevoie de sizeof pentru a calcula octeți. C++ new este un operator care returnează un pointer tipizat și apelează constructori. Asociați malloc() cu free(), iar new cu delete.

Da. Asistenții de codare prin inteligență artificială redactează apeluri malloc(), inserează verificări NULL și semnalează apeluri free() lipsă sau scurgeri de informații și pot explica aritmetica pointerilor. Compilează și testează întotdeauna codul generat înainte de a-l considera de încredere.

Copilotul GitHub sugerează malloc(), sizeof() și linii free() potrivite dintr-un comentariu care descrie intenția ta. RevVizualizați fiecare sugestie pentru verificările NULL lipsitoare și scurgerile de informații înainte de compilare.

Rezumați această postare cu: