Кўрсаткичларни осилиб қолиши дастурчиларнинг кенг тарқалган хатоликларидан биридир. Агарда кўрсаткич мурожаат қилган объектни delete оператори орқали ўчирсак ва бу кўрсаткичга 0 қиймати ўзлаштирилмаса, бу ҳолда жорий кўрсатгич осилиб қолади. Кейинчалик дастурда бу кўрсаткичдан фойдаланиш турли муаммоларни келтириб чиқариши мумкин. Кўрсаткичнинг осилиб қолишида туғиладиган муаммо қуйидаги муаммога ўхшашдир. Почта хизмати янги офисга кўчди, сиз эса унинг олдинги телефонига қўнғироқ қилишни давом эттирасиз. Агарда бу номер ўчириб қўйилган бўлса яхши, бу катта муаммони туғдирмайди. Лекин, бу номер қандайдир ҳарбий заводга берилган бўлса, у ҳолда юз берадиган ҳолатни тасаввур қилишингиз мумкин.
Бир сўз билан айтганда, кўрсаткичлар устида delete операторини ишлатишда эҳтиёт бўлиш лозим. Бу ҳолда, агарда кўрсаткичга 0 қиймат ўзлаштирилмаса у олдинги қийматини, яъни ўчирилган объект адресини ўзида сақлайди. Дастурни ишлаши давомида айнан шу адресга бошқа объект аниқланиши мумкин, чунки олдинги объект delete оператори орқали ўчирилганидан сўнг, динамик хотирани бу қисмидан бемалол фойдаланиш мумкин бўлиб қолади. Натижада биз жорий кўрсаткичда биз умуман кутмаган объектга мурожаат ҳосил бўлиб қолади ва у дастурни ишлаш жараёнида нотўғри ҳодисаларни келтириб чиқариши мумкин. 8.9.- листингда осилиб қолган кўрсаткичларни ишлатилишига мисол келтирилган.
8.9. – листинг. Кўрсаткични осилиб қолишига мисол.
// 8.9. – листинг.
// Кўрсаткични осилиб қолишига мисол
typedef unsigned short int ushort;
# inсlude
int main()
{
ushort * pInt = new ushort
*pInt = 10;
cout <<”* pInt:”<<* pInt <
delete pInt;
long * plong = new long;
*pLong = 90000;
cout << “*pLong: ” <<*pLong <
*pInt=20 //бўш кўрсаткичга қиймат ўзлаштириш.
cout << “*pInt:”<<* pInt <
cout << “*pLong:”<<*pLong <
delete pLong;
return 0;
}
НАТИЖА:
* pInt : 10
* pLong: 90000
* pInt: 20
* pLong: 65556.
(Cизнинг натижаларингиз юқоридагилардан фарқ қилиши мумкин )
ТАҲЛИЛ
7 – сатрда pInt ўзгарувчиси ushort типига кўрсаткич сифатида эълон қилинади ва бу типдаги маълумотни сақлаш учун хотира ажратилади. 8 – сатрда бу кўрсаткичдаги адресга 10 қиймати ёзилади. 9 – сатрда эса у экранга чиқарилади. Кейин эса pInt учун ажратилган хотира delete оператори орқали бўшатилади. Бундан сўнг жорий кўрсаткич осилиб қолади.
11 – сатрда pLong номли янги кўрсаткич эълон қилинади ва унга new оператори орқали ажратилган хотиранинг адреси ўзлаштирилади. 12 – сатрда кўрсаткичнинг бу адресига 90000 сони ёзилади ва 13 – сатрда бу қиймат экранга чиқарилади.
14 – сатрда pInt кўрсатиб турган адресга 20 қиймат ёзилади. Лекин, бу кўрсаткич учун ажратилган жой бўшатилган эди. Шунинг учун бундай операция нокорректдир. Бундай ўзлаштириш нотўғри натижаларни келтириб чиқаради. 15 – сатрда pInt нинг янги қиймати экранга чиқарилади. Бу қиймат кутилганидек 20 га тенг экан. 16 – сатрда эса pLong кўрсаткичининг қиймати чиқарилди. Лекин унинг қиймати биз кутмаган натижага тенг – 65556. Бу ерда иккита савол туғилади:
Биз қандай қилиб pLong нинг қийматини ҳаттоки, уни ишлатмасдан туриб ўзгартирдик.
17 сатрда ўзлаштирилган қиймат қаерга жойлаштирилди.
Сиз албатта бу иккала савол ўзаро боғлиқ эканлигини пайқаган бўлсангиз керак. 17 – сатрга ўзлаштирилган қиймат pInt кўрсаткичи шу вақтгача кўрсатиб турган адресга ёзилди. Лекин бу адрес 11 – сатрда бўшатилган эди ва компилятор бу соҳани бошқа маълумотларни ёзиш учун ишлатган. pLong кўрсаткичи эълон қилинганда (13 – сатрда), олдин pInt кўрсаткичи мурожаат қилган хотира қисми у томонидан резервланди. (Айрим компютерларда бу ҳол бўлмаслиги ҳам мумкин). pInt кўрсатиб турган адресга 20 қийматнинг ёзилиши, шу адресда сақланаётган pLong кўрсаткичи кўрсатиб турган қийматни ўзгартиради. Чунки иккала кўрсаткич ҳам битта адресни кўрсатиб турибди. Шунинг учун олинган натижалар кутилганидек эмас.
Бир оз четга чиқиш бўлсада pLong кўрсаткичи адресидаги қиймат нима учун 65556 га тенг бўлиб қолганлигини батафсил кўриб чиқамиз.
pInt кўрсаткичи хотирани биз 10 сонини ёзган қисмини кўрсатиб турар эди.
delete оператори орқали биз компиляторга хотиранинг бу қисмида бошқа маълумотларни сақлашга имкон ҳосил қилдик, яъни хотирани бу жойини бўшатдик.
*pLong ўзгарувчисига 90000 қиймат ўзлаштирилди. Компьютерда long типи тўрт байт жой эгаллайди ва машина даражасида 90000 сони 5F 90 00 01 кўринишда ифодаланади.
Кейин pInt кўрсаткичига 20 қиймат ўзлаштирилди, у эса 16 – лик саноқ системасида 00 14 га эквивалент. Иккала кўрсаткич ҳам хотирани бир жойига мурожаат қилишидан 90000 сонининг олдинги икки байти қайта аниқланади. Натижада 00 14 00 01 сонига эга бўламиз.
pLong кўрсаткичидаги қийматни экранга чиқаришда байтлар тартиби 00 01 00 14 га ўзгаради ва бунга эквивалент бўлган сон 65556 ҳосил бўлади.
Do'stlaringiz bilan baham: |