De ce variabilele C sunt stocate în locații specifice de memorie?

Ieri am avut un interviu în care intervievatorul ma întrebat despre clasele de stocare unde sunt stocate variabilele.

Răspunsul războiului meu:

Local Variables are stored in Stack.       
Register variables are stored in Register
Global & static variables are stored in data segment.  
The memory created dynamically are stored in Heap.

Următoarea întrebare pe care mi-a pus-o a fost: de ce se stochează în acea zonă de memorie specifică? De ce nu se stochează variabila locală cod> înregistrați (deși am nevoie de o variabilă auto obișnuită, utilizată foarte frecvent în programul meu)? Sau de ce variabilele globale sau statice sunt not stocate în stack ?

Apoi am fost clueless. Vă rog să mă ajutați.

6
register variabilele nu pot fi stocate într-un registru.
adăugat autor user703016, sursa
Variabilele locale nu sunt întotdeauna stocate în teanc (sunt deseori aliniate sau mutate în registre). Înregistrările variabilelor nu sunt întotdeauna stocate în registre (adesea sunt mutate în stivă). Variabilele globale (inclusiv cele statice) nu sunt întotdeauna stocate în segmentul de date (acestea sunt adesea plasate în segmentul de text sau în hărți dedicate de memorie). Singura diferență dintre o variabilă registru și o locală non-registru este aceea că compilatorul respinge programele care iau adresa unei variabile de registru.
adăugat autor Dietrich Epp, sursa

5 răspunsuri

Deoarece spațiul de stocare determină domeniile și durata vieții variabilelor.

Alegeți o specificație de stocare în funcție de cerința dvs., și anume:
Durata de viață: Durata în care vă așteptați ca variabila specială să fie vie și validă. Domeniul de aplicare: Domeniul de aplicare (zonele) în care vă așteptați ca variabila să fie accesibilă.

Pe scurt, fiecare zonă de stocare oferă o funcție diferită și aveți nevoie de funcționalități diferite, prin urmare, diferite zone de stocare.

16
adăugat
: Dacă acesta este cazul atunci când declarăm o variabilă fun() {static int a; a ++;} atunci merg în altă funcție (presupun fun2 ) și apoi mă întorc la fun() cum o păstrează valoarea anterioară. deoarece durata de viață a static este în interiorul fun()
adăugat autor Rasmi Ranjan Nayak, sursa
Nu subliniez acest răspuns. Nu există nici un fel de domeniu și durata de viață în microprocesor. Există doar o zonă de memorie contiguă și undeva în această zonă este LIFO (stack).
adăugat autor Luka Rahne, sursa
Întrebarea este despre locul în care sunt stocate astfel de variabile și despre timpul și durata de aplicare. Vorbind în acest fel este ca și cum, standardul a spus așa. Nu am citit standardul, dar se pare că nu vorbește despre stack și heap, astfel încât să nu-i poți explica folosind scopurile și durata de viață.
adăugat autor Luka Rahne, sursa
@Als, register nu mandatează nimic orice . E doar o sugestie.
adăugat autor bdonlan, sursa
@RasmiRanjanNayak: Da, acesta este întregul punct al acesteia. Vrei ca o variabila a intr-o functie sa fie vii pe toata durata de viata a programului, deci alegeti stocarea static Nu conteaza unde compilatorul stocheaza aceasta variabila, standardul nu spune nimic despre el si este un detaliu al implementarii, dar standardul impune o variabila static sa fie viu pe tot parcursul durata vieții și menținerea stării sale.
adăugat autor Alok Save, sursa
@ bdonlan: bine reperat. register aflat în această listă a fost o tipo.Indeed register nu mandatează nimic .
adăugat autor Alok Save, sursa
@ralu, limbile de programare cum ar fi C vă oferă o abstractizare a unei platforme și programul compilat este garantat că are un anumit comportament observabil care realizează această abstractizare. Dacă nu doriți ca programul să fie programat în asamblare care să implementeze exact caracteristicile procesorului specific pentru care ați programat.
adăugat autor Jens Gustedt, sursa

Limba C nu definește unde sunt stocate vreo variabile. Cu toate acestea, definesc trei clase de stocare: statice, automate și dinamice.

Variabilele statice sunt create în timpul inițializării programului (înainte de main() ) și rămân în vigoare până la terminarea programului. Domeniul de aplicare al dosarului ("global") și variabilele statice intră sub incidența categoriei. În timp ce acestea sunt în mod obișnuit stocate în segmentul de date, standardul C nu impune acest lucru și, în unele cazuri (de exemplu, interpreți C), acestea pot fi stocate în alte locații, cum ar fi heapul.

Variabilele automate sunt variabile locale declarate într-un corp de funcții. Ele sunt create atunci când sau înainte de fluxul de programe ajunge la declarația lor, și distruse atunci când acestea ies din domeniul de aplicare; noi instanțe ale acestor variabile sunt create pentru invocarea funcțiilor recursive. O stivă este o modalitate convenabilă de a implementa aceste variabile, dar din nou, nu este necesară. Ați putea pune în aplicare automatele în heap, de asemenea, dacă ați ales, și ele sunt de obicei plasate în registre, de asemenea. În multe cazuri, o variabilă automată se va deplasa între teanc și heap în timpul vieții.

Rețineți că adnotarea register pentru variabilele automate este un sugestie - compilatorul nu este obligat să facă nimic împreună cu el și într-adevăr mulți compilatori moderni îl ignoră complet.

În cele din urmă, obiectele dinamice (nu există o astfel de variabilă dinamică în C) se referă la valorile create explicit folosind malloc , calloc sau alte funcții similare de alocare. Ele apar atunci când sunt create explicit și sunt distruse atunci când sunt eliberate în mod explicit. O grămadă este un loc convenabil pentru a pune aceste - sau, mai degrabă, se definește o grămadă bazată pe capacitatea de a face acest stil de alocare. Dar din nou, implementarea compilatorului este liberă să facă tot ce vrea. Dacă compilatorul poate efectua o analiză statică pentru a determina durata de viață a unui obiect dinamic, este posibil să îl poată muta în segmentul de date sau în stivă (cu toate acestea, câțiva compilatori C fac acest tip de "analiză de evadare").

În acest caz, principiul de bază este că standardul limbajului C definește numai cât timp există o valoare dată. Și un minim obligat pentru această viață la asta - poate rămâne mai mult decât este necesar. Exact cum să plasați acest lucru în memorie este un subiect în care implementarea limbii și bibliotecii are o libertate semnificativă.

12
adăugat
@SwanandPurankar, K & R nu este actualizat. Este un ghid conceptual bun, totuși, sau așa am auzit, dar dacă doriți să fiți punct de vedere tehnic în privința unor astfel de lucruri, este mai bine să vă referiți la spec. Specificația limbajului C nu vorbește despre "heap". Fie că este vorba de a pune ceva pe halda sau nu este o alegere a punerii în aplicare. Cu toate acestea, majoritatea implementărilor nu pun statice pe heap (cu toate acestea, există excepții rare, cum ar fi interpreți C).
adăugat autor bdonlan, sursa
Hei @ bdonlan, am răspuns același într-un interviu că statica este stocată pe Heap. Intervievatorul a fost ca "Ești greșit ... Te-ai referit vreodată la K & R și bla bla" ... Deci a fost greșit răspunsul meu? Ce înseamnă K & R?
adăugat autor Swanand, sursa

Este de fapt doar un detaliu de implementare care este convenabil.

Compilatorul ar putea, dacă dorea, să genereze variabile locale pe heap, dacă dorește.

Este mai ușor să le creați pe stivă, deoarece atunci când părăsiți o funcție, puteți regla pointerul cadrului cu o simplă adăugare/scădere în funcție de direcția de creștere a stivei și astfel eliberați automat spațiul utilizat pentru următoarea funcție. Crearea localnicilor pe halda ar însemna însă mai multă muncă de menaj.

Un alt punct este faptul că variabilele locale nu trebuie create pe stivă, ele pot fi stocate și utilizate doar într-un registru dacă compilatorul consideră că este mai potrivit și are suficiente registre pentru a face acest lucru.

1
adăugat

Variabilele locale sunt stocate în registre în majoritatea cazurilor, deoarece registrele sunt împinse și scoase din stivă când efectuați apeluri în funcție. Se pare că sunt în stack.

De fapt, nu există astfel de obiecte ca variabilele de registru, deoarece este doar un cuvânt cheie foarte rar folosit în C, care îi spune compilatorului să încerce să pună acest lucru în registre. Cred că majoritatea compilatorilor ignoră acest cuvânt cheie.

De ce te-a întrebat mai mult, pentru că nu era sigur dacă înțelegi profund subiectul. Este adevărat că variabilele registrului sunt practic pe stivă.

0
adăugat
Cele mai multe variabile sunt înregistrate în mod implicit. registru poate fi folosit doar pentru a spune compilatorului că o astfel de variabilă are prioritate pentru a intra în registru.
adăugat autor Luka Rahne, sursa
"registrele sunt împinse ... când faci apeluri de funcții" - unele sunt, altele pot conține argumente de funcționare, altele pot fi împinse doar de funcția apelată dacă consideră că are nevoie de mai multe registre și, în unele cazuri, procesoarele își susțin mecanismele proprii salvarea și restaurarea registrelor sans stack (de exemplu, UltraSparcs). De asemenea, nu este neobișnuit să existe machete locale și date textuale - este puțin probabil să se încadreze în registre, deci "local ... în registre în majoritatea cazurilor" fără clarificări care nu oferă o înțelegere. Apoi "variabilele de r
adăugat autor Tony Delroy, sursa
register nu este inutil, inseamna auto plus interdictia de a lua adresa variabilei. Deci, acesta este un indiciu de optimizare la fel ca restrict pentru parametrii pointer, de ex.
adăugat autor Jens Gustedt, sursa
vă amestecați cu diferite concepte. Registrele procesorului și cuvântul cheie register al limbii C. Pur și simplu spuneam ce specifică cuvântul cheie de limbă, nu are prea mult de-a face cu faptul că o variabilă este realizată într-un registru (de procesor) sau nu. Dacă doriți să fie doar un nume greșit, înlocuiți register (cuvântul cheie) cu addressless și sunteți mai aproape de ceea ce înseamnă în C.
adăugat autor Jens Gustedt, sursa

în sistemele încorporate avem diferite tipuri de memorii (citiți numai non volatile (ROM), citiți scriere non volatile (EEPROM, PROM, SRAM, NVRAM, flash), volatile (RAM)) și, de asemenea, și, de asemenea, persistă după ciclul de putere, se pot schimba și, de asemenea, persistă după ciclismul de putere, se pot schimba oricând) pe datele pe care le avem. avem secțiuni diferite, deoarece trebuie să optimizăm cerințele noastre de date pe diferite tipuri de memorii disponibile.

0
adăugat