2. praktikum - Stacki vaatlemine
Selle praktikumi eesmärk on avastada call stack ja seda veidi lahata.
NB! Tänast harjutust teeme klassi arvutites, sest Dijkstra on ümberehitamisel.
Ülesanne
Meie töömeetod on järgmine: kirjutame programmi, milles on hulk muutujaid ning seejärel proovime aru saada kuidas nad mällu asetuvad. Selleks kasutame pointereid ja eelmise praktikumi mälu tõlgendamise kohta õpitut.
= Programm
Kirjutage programm mille funktsioonis main() on deklareeritud:
- vähemalt 3 täisarvulist muutujat erinevate vaikimisi väärtustega,
- string
Lisage programmile funktsioon foo(int i), milles on deklareeritud:
- vähemalt 2 erinevat täisarvulist muutujat vaikimisi väärtustatult,
See programm ei pea otseselt midagi tegema, aga funktsioon foo() võiks käivituda.
Uurimine
- Täienda programmi nii, et ta trükib välja kõigi muutujate mäluaadressid (printf() funktsiooni asendustähisena %p tõlgendab mäluaadressi mõistlikult). Muutuja muudab aadressiks tehe &.
- Vaata funktsioonis foo() esimese deklareeritud muutuja ees ja selle taga olevaid mäluaadresse. (Kindlas kohas mälu vaatamiseks kasuta * tehet).
- Kas on võimalik minna kaugemale? Kas foo sees leitud aadressi muutmisel on võimalik leida funktsiooni main() muutujad? (On, aga proovi seda teha)
- Kas string main() funktsioonis paikneb ka stackis?
- Kommenteeri välja ühe main() muutuja kõik viited. Jälgi, et su programm neid ei kasutaks -- kas neid on ka pärast seda foo() alt leitud mäluaadressi abil võimalik vaadata?
- Lisa mõnele muutujale võtmesõna static ning kontrolli tema olemasolu.
- Taasta muutujate seis. Kirjuta funktsioon, mis püüab kogu stacki välja trükkida (4 baiti iga printf() väljakutse kohta, "%08x\n" näiteks. Võib olla kasulik trükkida välja ka muutuja tõlgendus kümnendsüsteemis ja 4 erineva charina.) Kuna tahame näha mis on mälus pärast stacki lõppu, on programmi vältimatu kokkujooksmine ainult teretulnud!
Stacki juurde tuleme debuggerit uurides korra tagasi.