C Статично и автоматично разпределение

Когато се стартира програма C, как тя иска от операционната система достатъчно място в паметта за статични променливи? И докато работи, как пита паметта на операционната система за автоматични променливи?

Бих искал също да знам как освобождава тези пространства от паметта след изпълнение.

Моля, опитайте се да бъдете възможно най-точни. Ако операционните системи се различават в обясненията си, моля, дайте предпочитание на UNIX-подобните.


person Thiago Bezerra    schedule 02.03.2015    source източник


Отговори (3)


Глобалните променливи и тези със статичен живот обикновено се съхраняват в сегмент от данни, който се настройва от програмата за зареждане на изпълними файлове на операционната система.

Този товарач вероятно прави това, което @John Zwinck каза за Unix. В Windows има VirtualAlloc например, който може да се използва и за разпределяне на памет в адресното пространство на друга програма.

Локалните променливи обикновено се съхраняват в така наречения стек. Разпределенията в стека са доста бързи, тъй като обикновено се състоят само от модификация на регистъра на указателя на стека (sp, esp, rsp при семейството процесори x86). Така че, когато имате int (размер: 4 байта), този регистър просто ще бъде намален с 4, докато стекът расте надолу. В края на обхвата старото състояние на регистъра на стека се възстановява.

Също така това прави препълването на стека опасно, когато можете да презапишете други променливи в стека, които не трябва да се променят, като адреси за връщане на извиквания на функции.

Динамичните променливи са променливи, разпределени с помощта на malloc (C) или new (C++) или някоя от специфичните за операционната система функции за разпределение. Те се поставят върху така наречената купчина. Те живеят, докато не бъдат изчистени с помощта на free/delete/os-specific-deallocator или програмата излезе (в този случай нормална операционна система се грижи за почистването).

Освен това динамичното разпределение е най-бавното от трите, тъй като изисква извикване на операционната система.

person Felix Bytow    schedule 02.03.2015

Разпределението на паметта на Unix-подобни системи се извършва чрез извиквания към операционната система с помощта на sbrk() и mmap() API.

sbrk() се използва за уголемяване на "сегмента от данни", който е непрекъснат диапазон от (виртуални) адреси. mmap() се използва в много съвременни системи като нещо като допълнение към това, защото може да разпределя парчета, които по-късно могат да бъдат освободени независимо (което означава, че няма да останат "дупки", както може да се случи с sbrk()).

В C имате malloc() като насочен към потребителя API за разпределяне на памет. Можете да прочетете повече за това как това се съпоставя с функциите от ниско ниво, които споменах по-рано, тук: Как се прилагат malloc и free?

person John Zwinck    schedule 02.03.2015

Статичните променливи се намират в BSS сегмента зад кода. Автоматичните променливи се намират в стека в края на виртуалната памет на процеса. И двете се дефинират по време на компилиране. След това оформлението на паметта се създава при стартиране на програмата. brk(), sbrk() и mmap() могат да манипулират виртуалната памет (в частност купчината) по време на изпълнение (напр. с malloc()/free()), но тези функции не са свързани със статични и автоматични променливи!

person Bernhard    schedule 02.03.2015