Programmēšanas valodu grāmatās tiek skaidrots, ka vērtību tipi tiek veidoti stack, bet atsauču tipi tiek veidoti heap, nepaskaidrojot, kas ir šīs divas lietas. Neesmu lasījis skaidru skaidrojumu par to. Es saprotu, kas ir kaudze. Bet,
Stack:
Kopa:
delete
, delete[]
vai free
.new
vai malloc
.Piemērs:
int foo()
{
char *pBuffer; //<--nothing allocated yet (excluding the pointer itself, which is allocated here on the stack).
bool b = true; // Allocated on the stack.
if(b)
{
//Create 500 bytes on the stack
char buffer[500];
//Create 500 bytes on the heap
pBuffer = new char[500];
}//<-- buffer is deallocated here, pBuffer is not
}//<--- oops there's a memory leak, I should have called delete[] pBuffer;
Stack Kad izsaucat funkciju, tās argumenti un daži citi pieskaitāmie izdevumi tiek novietoti uz kaudzes. Tur tiek saglabāta arī informācija (piemēram, par to, uz kurieni doties atgriešanās brīdī). Kad deklarējat mainīgo savā funkcijā, šis mainīgais arī tiek piešķirts uz kaudzes.
Atdalīt kaudzi ir diezgan vienkārši, jo vienmēr tiek izdalīts pretējā secībā, nekā tika izdalīts. Stāvs tiek pievienots, ieejot funkcijās, un attiecīgie dati tiek noņemti, izejot no tām. Tas nozīmē, ka jūs parasti paliekat nelielā kaudzes apgabalā, ja vien neizsaucat daudz funkciju, kas izsauc daudz citu funkciju (vai neradāt rekursīvu risinājumu).
Krāvums Kaudze ir vispārīgs nosaukums vietai, kur jūs ievietojat datus, ko izveidojat "lidojuma laikā". Ja jūs nezināt, cik daudz kosmosa kuģu jūsu programma izveidos, jūs, visticamāk, izmantosiet operatoru new (vai malloc, vai līdzvērtīgu operatoru), lai izveidotu katru kosmosa kuģi. Šī piešķiršana uz kādu laiku paliks, tāpēc, visticamāk, mēs atbrīvosim lietas citā secībā, nekā tās izveidojām.
Tādējādi kaudzīte ir daudz sarežģītāka, jo galu galā neizmantotie atmiņas apgabali mijas ar neizmantotajiem - atmiņa tiek fragmentēta. Nepieciešamā lieluma brīvas atmiņas atrašana ir sarežģīta problēma. Tāpēc no kaudzes ir jāizvairās (lai gan to joprojām bieži izmanto).
Implementācija Gan kaudzes, gan kaudzes īstenošana parasti ir atkarīga no izpildes laika/operētājsistēmas. Bieži vien spēles un citas lietojumprogrammas, kurām ir būtiska veiktspēja, rada savus atmiņas risinājumus, kas paņem lielu daļu atmiņas no kaudzes un pēc tam to izlieto iekšēji, lai izvairītos no atkarības no operētājsistēmas atmiņas nodrošināšanas.
Tas ir praktiski izmantojams tikai tad, ja atmiņas izmantošana atšķiras no normas, t. i., spēlēs, kurās ar vienu milzīgu operāciju ielādējat līmeni un ar citu milzīgu operāciju varat to visu izmest prom.
Fiziskā atrašanās vieta atmiņā Tas ir mazāk svarīgi, nekā jūs domājat, jo pastāv tehnoloģija, ko sauc par virtuālo atmiņu, kas liek jūsu programmai domāt, ka jums ir piekļuve noteiktai adresei, lai gan fiziskie dati atrodas kaut kur citur (pat cietajā diskā!). Adreses, kuras jūs saņemat kaudzē, ir pieaugošā secībā, jo jūsu izsaukumu koks kļūst dziļāks. Krāvuma adreses ir neparedzamas (t. i., atkarīgas no implementācijas) un, atklāti sakot, nav svarīgas.
Steks ir atmiņas daļa, ar kuru var manipulēt, izmantojot vairākas galvenās asamblēšanas valodas instrukcijas, piemēram, 'pop' (vērtības noņemšana un atgriešana no kaudzes) un 'push' (vērtības iebīdīšana kaudzē), kā arī call (apakšprogrammas izsaukšana - ar šo instrukciju uz kaudzes tiek ievietota adrese, no kuras jāatgriežas) un return (atgriešanās no apakšprogrammas - ar šo instrukciju no kaudzes tiek izņemta adrese un uz to pārlēkts). Tas ir atmiņas apgabals zem kaudzes rādītāja reģistra, ko var iestatīt pēc vajadzības. Steks tiek izmantots arī argumentu nodošanai apakšprogrammām, kā arī vērtību saglabāšanai reģistros pirms apakšprogrammu izsaukšanas.
Kaudzīte ir atmiņas daļa, ko operētājsistēma piešķir lietojumprogrammai, parasti izmantojot syscall, piemēram, malloc. Mūsdienu operētājsistēmās šī atmiņa ir lapu kopums, kam piekļuve ir tikai izsaucošajam procesam.
Kaudzes lielumu nosaka darbības laikā, un pēc programmas palaišanas tā parasti nepalielinās. C programmā kaudzītei ir jābūt pietiekami lielai, lai tajā varētu ievietot visus katrā funkcijā deklarētos mainīgos. Stāvs dinamiski palielināsies pēc vajadzības, bet galu galā izsaukumu veic operētājsistēma (tā bieži vien palielinās kaudzi par lielāku vērtību nekā malloc pieprasītā vērtība, lai vismaz dažām turpmākajām malloc darbībām nebūtu jāatgriežas pie kodola, lai iegūtu vairāk atmiņas. Šādu uzvedību bieži vien var pielāgot)
Tā kā pirms programmas palaišanas ir piešķirts kaudze, jums nekad nav nepieciešams veikt malloc pirms kaudzes izmantošanas, tāpēc tas ir neliela priekšrocība. Praksē mūsdienu operētājsistēmās, kurās ir virtuālās atmiņas apakšsistēmas, ir ļoti grūti paredzēt, kas būs ātrs un kas lēns, jo tas, kā tiek realizētas lapas un kur tās tiek glabātas, ir implementācijas detaļa.