По-прости начини за работа с динамична памет при Си и Си++

Начините, описани тук, са приложими при програмиране както на Си, така и на Си++. За по-голяма конкретност обаче, ще се придържаме към обектноориентирани примери за Си++.

I начин — притежателни и непритежателни указатели

При този метод разделяме указателите, дефинирани във всеки от класовете, на два вида — притежателни и непритежателни. Едните показват собственост, а другите не. Например ако в клас UNIVERSITY е дефиниран указател faculties сочещ към свързан списък на факултетите на съответния университет, този указател ще бъде притежателен. Указател rector обаче, който сочи към ректора на университета няма да бъде притежателен, защото университетът не е собственик на своя ректор.

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

Макар че при конкретни структури често е ясно кои указатели трябва да бъдат притежателни, при абстрактни структури това съвсем не е така. Например един свързан списък собственик ли е на своите елементи? Зависи. Горният списък от факултети би трябвало да бъде техен собственик, за да може при унищожаването на университета да се унищожат автоматично и факултетите. Свързан списък от максимизираните прозорци обаче едва ли ще трябва да ги затвори при унищожаването си.

Поздсказка

За да се предпазваме от грешки, е препоръчително по някакъв начин името на указателите да показва дали той е притежателен и ли не. Например имената на притежателните указатели може да започват с главна буква, а на непритежателните — с малка.

II начин — пулове от непритежавани обекти

Този начин е просто допълнение на първия. Има обекти, за които не е ясно кой трябва да ги притежава (т.е. кой трябва да ги унищожава). В такъв случай групираме тези обекти според времето, през което те трябва да съществуват, и за всяка от така получените групи създаваме специален обект пул. Единственото предназначение на пула е да съдържа указатели към обектите от групата, за която той е създаден. Приемаме, че тези указатели са притежателни. Когато трябва унищожим обектите от дадена група, ние просто унищожаваме техния пул.

III начин — пул с броячи

Подобен метод се използва от ядрото Линукс. И тук указателите са притежателни и непритежателни, но освен това и обектите се делят на да два вида — притежавани и непритежавани. С притежаваните обекти се работи също както и при I начин. За разлика от II начин обаче, тук не групираме непритежаваните обекти в пулове, а вместо това ги регистрираме в един специален пул, който освен указатели съдържа и броячи за всеки от указатели. Всеки модул от програмата, който е заинтересован от даден непритежаван обект, го регистрира в пула, като по такъв начин броячът му се увеличава с единица. Когато даден модул реши, че даден непритежаван обект повече не му е нужен, той съобщава това в пула. Така броячът му ще се намали с единица. Когато броячът стане нула пулът унищожава непритежаваният обект.

IV начин — брояч за всеки от обектите

При този начин всеки от обектите съдържа и брояч. Във всеки момент от времето този брояч показва колко указателя сочат към обекта. Така например когато присвояваме стойност на някакъв указател p ние трябва първо да намалим брояча на обекта, към който p е сочил, а след това да увеличим брояча на обекта, към който p започва да сочи. Когато броячът на даден обект стане нула, обектът се унищожава. Неговият деструктор намалява броячите на обектите, към които сочат указателите в него; това може да доведе до унищожаване на още обекти.

Този метод не може да се използва при циклични структури. Да разгледаме примера, който вече използвахме. Класът UNIVERSITY съдържа указател rector към своя ректор. Да допуснем сега, че ректорът е обект от клас HUMAN, който съдържа указател employment към своята месторабота. В частност обектът на ректора на университета ще съдържа указател към обекта на своя университет, който пък от своя страна съдържа указател към обекта на своя ректор. Така излиза, че университетът и ректорът сочат взаимно един към друг и по такъв начин броячите никога не могат да станат нула.