Cum eliberez memoria în C? (Programare, C, Gestionarea Memoriei, Malloc)

andrey a intrebat.

Scriu un cod care are o mulțime de array-uri 1 & 2 dimensionale. Am primit „error: can’t allocate region” și cred că este din cauză că este alocată prea multă memorie. Folosesc funcțiile „malloc” și „free”, dar nu sunt sigur că le folosesc corect. Poate știți unde aș putea vedea exemple bune de gestionare a memoriei în C?

Deci… Încerc doar să fac să funcționeze un algoritm și deocamdată codul ăsta e doar funcție după funcție..

//memory allocation for 1D arrays
buffer = malloc(num_items*sizeof(double));

//memory allocation for 2D arrays
double **cross_norm=(double**)malloc(150 * sizeof(double *));
for(i=0; i<150;i++)
    {
        cross_norm[i]=(double*)malloc(num_items*sizeof(double));
    }

    //code
Window(N, window_buffer);
STFTforBMP(buffer,N,f, window_buffer);
getMagnitude(buffer,f, N, magnitude);
calculateEnergy(flux,magnitude, f);
calculateExpectedEnergy(expected_flux, candidate_beat_period, downbeat_location, f);
calculateCrossCorrelation(cross, flux, expected_values, f);
findLargestCrossCorrelation(&cross_max, cross, f);
normalizeCrossCorrelation(cross_norm, &cross_max, cross, f);
    ...............

Cum ar trebui să folosesc free funcția?

Comentarii

  • Poate că ar fi mai constructiv să ne arăți ce ai încercat ? –  > Por cnicutar.
  • ar trebui să oferiți exemple de ceea ce faceți. altfel întrebarea dvs. este prea generală pentru a răspunde dincolo de: citiți specificațiile. –  > Por akira.
2 răspunsuri
Alok Save

Trebuie să free() memoria alocată în ordinea inversă exactă a modului în care a fost alocată folosind malloc().

Rețineți că ar trebui să eliberați memoria numai după ce ați terminat de utilizat indicatoarele alocate.

alocarea memoriei pentru array-uri 1D:

    buffer = malloc(num_items*sizeof(double));

dezalocarea memoriei pentru array-uri 1D:

    free(buffer);

alocarea memoriei pentru array-uri 2D:

    double **cross_norm=(double**)malloc(150 * sizeof(double *));
    for(i=0; i<150;i++)
    {
        cross_norm[i]=(double*)malloc(num_items*sizeof(double));
    }

Dezafectarea memoriei pentru matricele 2D:

    for(i=0; i<150;i++)
    {
        free(cross_norm[i]);
    }

    free(cross_norm);

Jason

De fapt, nu puteți „elibera” manual memoria în C, în sensul că memoria este eliberată de la proces înapoi la sistemul de operare … atunci când apelați malloc(), , libc-runtime-ul subiacent va solicita de la sistemul de operare o regiune de memorie. Pe Linux, acest lucru se poate face printr-un apel relativ „greu” precum mmap(). Odată ce această regiune de memorie este alocată programului dvs., există o listă legată numită „free store” care gestionează această regiune de memorie alocată. Atunci când apelați malloc(), , se caută rapid un bloc de memorie liber cu dimensiunea solicitată în „free-store”. Apoi ajustează lista legată pentru a reflecta faptul că a fost luată o bucată de memorie din fondul de memorie alocat inițial. Atunci când apelați free() blocul de memorie este plasat din nou în stocul liber ca un nod al listei legate care indică faptul că este o bucată de memorie disponibilă.

Dacă solicitați mai multă memorie decât cea aflată în free-store, libc-runtime va solicita din nou mai multă memorie de la sistemul de operare până la limita capacității acestuia de a aloca memorie pentru procesele în curs de execuție. Totuși, atunci când eliberați memorie, aceasta nu este returnată sistemului de operare … de obicei, este reciclată înapoi în free-store, unde poate fi utilizată din nou printr-un alt apel către malloc(). Astfel, dacă efectuați multe apeluri către malloc() și free() cu solicitări de dimensiuni diferite ale memoriei, ar putea, teoretic, să provoace o situație numită „fragmentare a memoriei”, în care există suficient spațiu în depozitul liber pentru a aloca blocul de memorie solicitat, dar nu suficient contiguă pentru dimensiunea blocului pe care l-ați solicitat. Astfel, apelul către malloc() eșuează, iar dvs. rămâneți efectiv „în afara memoriei”, chiar dacă este posibil să existe o mulțime de memorie disponibilă ca număr total de octeți în free-store.

Comentarii

  • Mi se pare mie sau OP întreabă altceva, iar răspunsul (deși frumos) explică altceva? –  > Por Alok Save.
  • OP și-a actualizat întrebarea în timp ce eu îmi scriam răspunsul (presupun că ca răspuns la unele dintre comentarii) … M-am gândit că răspunsul meu ar putea fi în continuare instructiv, chiar dacă nu răspunde explicit la întrebarea sa actualizată. Întrebarea sa originală nu avea niciun cod și era practic că folosește malloc și free, , dar tot se termină cu o eroare de tip „can’t allocate region”. Mi s-a părut o posibilă fragmentare a memoriei, așa că m-am gândit că acesta ar putea fi un răspuns bun. –  > Por Jason.
  • Ah, înțeleg. Bine. Este o explicație drăguță, deși Întrebarea schimbată o face să pară deplasată. în orice caz, ai +1 pentru efortul depus. –  > Por Alok Save.
  • Cum ați rezolva o astfel de fragmentare? –  > Por RastaJedi.
  • Există o serie de opțiuni, dar o strategie de coborâre ar fi să folosiți un tip de alocator de memorie personalizat de blocuri mici de memorie care preia o bucată mare de memorie de la sistemul de operare și apoi alocă memoria din cadrul acelui bloc mare într-un mod care să evite fragmentarea memoriei din alocările aleatorii de dimensiune a memoriei –  > Por Jason.