Tablouri mari: stivă și memorie dinamică în C++
Estimează memoria unui tablou înainte de rulare. Separă durata de viață, zona de alocare și limita totală, fără să presupui o limită universală a stivei.
În acest material
Un tablou cu foarte multe elemente poate depăși o limită de memorie chiar dacă indicii sunt corecți. Primul pas este să estimezi numărul de octeți, apoi să verifici unde și cât timp este păstrată acea memorie.
Calculează dimensiunea reală
Pentru un tablou cu n elemente de tip T, spațiul elementelor este n înmulțit cu sizeof(T). Pentru o matrice, înmulțești și cu numărul coloanelor. Folosește dimensiunea tipului din mediul concret; nu transforma o presupunere despre int într-o regulă universală.
O matrice cu 10000 de linii și 10000 de coloane are o sută de milioane de elemente. Dacă fiecare element ocupă patru octeți în mediul folosit, doar elementele cer aproximativ 400 de milioane de octeți, înaintea altor date ale programului.
Memoria locală poate avea o limită distinctă
Obiectele locale cu durată automată sunt gestionate în mod obișnuit folosind stiva de execuție. Un tablou local foarte mare poate depăși limita disponibilă pentru aceasta, chiar dacă limita totală a procesului pare mai generoasă.
Limita exactă depinde de platformă și configurare. Nu presupune că o valoare observată pe calculatorul tău se aplică evaluatorului. Apelurile recursive adaugă și ele cadre active; datele locale mari din fiecare apel pot amplifica rapid consumul.
O matrice 10000×10000 are 100000000 de elemente. La patru octeți pe element în mediul ales, elementele ocupă 400000000 de octeți.Mărește schema ↗
Mutarea alocării nu reduce numărul elementelor
Un tablou static sau global are altă durată de viață decât un obiect local automat. Un vector își gestionează de obicei elementele prin alocare dinamică. Aceste variante pot evita o limită specifică stivei, dar nu elimină limita totală de memorie.
Dacă algoritmul cere prea multe elemente, schimbarea zonei de alocare nu îl face eficient. Poate fi nevoie de comprimarea stărilor, păstrarea numai a două linii ale unei matrice de calcule sau alegerea unei reprezentări rare.
Verifică și copiile
Transmiterea unei structuri mari prin valoare, păstrarea mai multor matrici simultan și vectorii temporari pot dubla sau multiplica spațiul aparent necesar. Desenează ce obiecte coexistă la momentul de consum maxim, nu doar ce obiecte apar în declarațiile inițiale.
Testează limita maximă permisă de enunț și măsoară în mediul potrivit. Un test mic confirmă unele rezultate, dar spune foarte puțin despre memoria necesară la dimensiunea maximă.
Recapitulează tablourile, alocarea dinamică și complexitatea memoriei.
Întrebări frecvente
Cum estimez memoria unui tablou sau a unei matrice?
Înmulțește numărul elementelor cu sizeof al tipului lor. Pentru o matrice n×m, spațiul elementelor este n·m·sizeof(T); verifică separat celelalte structuri și copii din program.
De ce poate eșua un tablou local mare?
În mediile obișnuite, tablourile locale automate folosesc stiva, care poate avea o limită separată și relativ mică. Dimensiunea permisă depinde de mediul de execuție, nu doar de memoria fizică a calculatorului.
Alocarea dinamică elimină limita de memorie?
Nu. Poate evita limita specifică stivei, dar memoria totală rămâne limitată. Verifică dimensiunile, numărul copiilor și durata de viață a datelor indiferent de locul alocării.