Documente Academic
Documente Profesional
Documente Cultură
INTRODUCERE
Alocarea dinamică permite crearea, exploatarea şi distrugerea unor obiecte în timpul execuției
programului, la inițiativa programatorului. Se foloseşte dacă se poate obține o reducere a dimensi-
unii programului prin reducerea zonei de date incluse în program. Se foloseşte în cazul datelor de
dimensiune variabilă sau în cazul unor structuri cu număr variabil de elemente, număr cunoscut
abia la execuție.
Odată alocată memoria, acea zona poate fi tratată ca fiind un tablou și accesată astfel, pentru
că alocarea se face în mod secvențial.
Limbajul C nu dispune de un sistem încorporat pentru alocarea şi eliberarea variabilelor dinam-
ice, așa cum are pentru variabile statice şi locale. Biblioteca standard C oferă un set de funcții pen-
tru alocarea şi eliberarea variabilelor dinamice. Funcțiile ce permit alocarea dinamică sunt de-
clarate în fişierele antet:
stdlib.h
Alocarea dinamică implică folosirea pointerilor. Este necesară folosirea conversiilor de tip şi a
operatorului sizeof(). Pointerii obtinuți cu funcțiile malloc() şi calloc() se vor dealoca numai cu
funcția free().
Se recomandă testarea pointerilor obținuți înainte de folosire şi înainte de dealocare!!!
MALLOC()
void* malloc(unsigned nr_oct);
Zona de memorie alocată este echivalentă cu un tablou de 20 de întregi, iar elementele lui pot fi
referite:
• cu operatorul de indexare: p[0], p[i]
• sau cu operatorul de indirectare: *p, sau mai general, *(p+i)
Se recomandă testarea pointerului obținut înainte de folosire!!
FREE()
void free(void *);
Permite eliberarea zonelor de memorie alocate anterior, prin specificarea unui pointer ce
conține adresa de început a zonei ce se dorește a fi eliberată. Dacă se apelează cu un parametru
NULL rezultatele sunt imprevizibile.
Dacă datele din heap nu mai sunt necesare se recomandă eliberarea zonei aferente
După eliberare:
• nu poate folosi din nou acea zonă de memorie cu pointerul eliberat
• pointerul eliberat rămâne vizibil, dar valoarea lui nu are nici o semnificație
• până la sfârșitul blocului acest pointer poate fi refolosit la o altă alocare sau ca simplu pointer
către o dată căreia i se asociază
Regulă practică: numărul de apeluri către funcții de alocare trebuie să fie egal cu numărul de
apeluri către funcții de dealocare
REALLOC()
void *realloc(void *block, size_t size);
Permite realocarea memoriei prin extinderea sau comprimarea unui bloc ce a fost alocat anteri-
or cu una din funcțiile malloc(), calloc() sau chiar realloc()
• dacă size == 0 blocul de memorie este eliberat şi se returnează valoarea NULL
• dacă block == NULL, funcția realloc( ) lucrează la fel ca şi funcția malloc( )
• funcția returnează un pointer la zona de memorie realocată în caz de succes sau valoarea
NULL în caz de eşec sau dacă size == 0
• în urma ajustării dimensiunii blocului de memorie este posibilă mutarea conținutului memoriei
în altă zonă, datele fiind păstrate
copiază n octeți de la sursă la destinație, însă copierea se poate opri în următoarele situații:
• la întâlnirea caracterului c (ce este copiat la destinație)
• s-au copiat deja n octeți la adresa de destinație
Returnează adresa din blocul destinație ce urmează după caracterul c, dacă acesta a fost copi-
at sau valoarea NULL în caz contrar
memicmp() face acelaşi lucru, dar fără a ține cont de litere mari, respectiv litere mici (ignoring
case) - DOAR ÎN COMPILATOARE MICROSOFT!!
Interschimbarea octeților
#include <stdlib.h>
© Adriana Stan, Ligia Chiorean, Mircea Vaida 3 Programarea Calculatoarelor - Limbaje
void swab(char *src, char *dest, int n);
preia primii n octeți de la sursă, aplică interschimbarea fiecărei perechi şi depune rezultatul la
destinație
dacă n este par, interschimbarea se aplică pentru toți octeții, începând cu primul octet
dacă n este impar, interschimbarea se aplică numai la primii (n-1) octeți, începând cu primul
octet
EXEMPLE
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main(void){
int i,n, *tab=NULL;
printf("\nIntroduceti dimensiunea tablolului: ");
scanf("%d", &n);
if((tab = (int *)malloc(n * sizeof(int)))) {
printf("\nIntroduceti elementele tablolului: \n");
for(i=0; i<n; i++) {
printf("\t elementul %d: ", i+1);
scanf("%d", tab+i);
}
for(i=0; i<n; i++)
printf("\n tab[%d] = %d", i, tab[i]);
//printf("\n tab[%d] = %d", i, *(tab +i));
printf("\n");
}
else
printf("\nAlocare nereusita !");
if(tab)
free(tab);
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main(void){
// dealocare
if(tab)
free(tab);
}// end main
#include <stdio.h>
#include <stdlib.h>
int main(void){
int i, j, m,n, **tab;
printf("\n Introduceti numarul de linii: ");
scanf("%d", &m);
if((tab = (int **)malloc(m*sizeof(int)))){
printf( "\n Introduceti numarul de coloane: ");
if(tab){
for(i=0; i<m; i++)
free (tab[i]);
free(tab);
}
return 0;
}
int main(void){
char str[] = "abcdefghijklmnopqrstuvwxyz";
printf("%s\n", str);
memset(str,'a',5);
printf("%s\n", str);
}//end main
int main(void){
char source[] = "a fost odata ca-n povesti";
char dest[6];
memcpy(dest, source, sizeof dest);
for(size_t n = 0; n < sizeof dest; ++n)
printf("%c",dest[n]);
}//end main
int main(void){
float values[ ] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
float empty[5];
int i;
memmove(empty, values, sizeof(values));
for (i = 0; i < 5; i++)
printf("%3.1f\t", empty[i]);
printf("\n");
}
#include <stdio.h>
#include <stdlib.h>
int main(void){
char *a = "AAA";
char *b = “aaa";
return 0;
}
9. Interschimbarea octeților
#include <stdio.h>
#include <memory.h>
#include <string.h>
int main(void) {
char *source = "ABCD";
char target[10];
memset(target, NULL, sizeof(target));
swab(source, target, strlen(source));
printf("Sursa: %s \n", source);
printf("Destinatie: %s\n", target);
TEME
1. Să se scrie un program care citeşte n numere reale, pe care le stochează într-un tablou alocat
dinamic, afişează suma elementelor negative citite, iar la sfârşit eliberează zona de memorie
alocată.
6. Folosiţi alocarea dinamică pentru o matrice m x n cu valori întregi (m, n <7). Initializaţi ele-
mentele matricii. Dacă matricea este pătratică, folosiţi metoda lui Sarrus pentru a obţine valoarea
determinantului. Afişaţi rezultatul şi eliberaţi memoria.
7. Să se scrie o aplicaţie C care alocă dinamic memorie necesară pentru stocarea a 10.000 de
numere întregi. Programul iniţializează numerele cu valori aleatoare între 1 şi 100 (folosiţi funcţia
rand()). Scrieţi o funcţie care afişează cele mai frecvente 10 numere şi numărul lor de apariţii în
tabloul iniţial.
8. Să se scrie o aplicaţie C în care se alocă dinamic memorie pentru n numere întregi, numere
ce vor fi citite de la tastatură. Să se scrie funcţia care extrage radicalul din fiecare număr şi
stochează valorile obţinute într-un alt tablou alocat dinamic. Să se afişeze numerele iniţiale şi
valorile din tabloul format. Eliberaţi la sfârşit memoria alocată.
9. Scrieţi un program în care se citesc n şiruri de caractere şi se concatenează într-un alt şir, alo-
cat dinamic. Repetaţi operaţia de câte ori doreşte utilizatorul. După fiecare afişare a şirului obţin-
ut prin concatenare eliberaţi memoria alocată dinamic.
10. Să se scrie o aplicaţie C, care alocă dinamic memorie pentru stocarea elementelor unei ma-
trici de dimensiune nxn. Să se scrie o funcţie care calculează suma numerelor pozitive pare de
sub diagonala principală şi o funcţie pentru afişarea matricei. Să se afişeze matricea şi suma
cerută. Eliberaţi memoria alocată dinamic.
11. Generați un tablou de pointeri către șiruri constante folosind funcția strdup() sau o funcție
specifică. Afișați valorile pare din tablou.