[Bermain muzik]
>> DOUG LLOYD: OK jadi cadangan sebelum memulakan di sini.
Jika anda tidak menonton video pada Penunjuk anda mungkin mahu untuk berbuat demikian pertama.
Kerana video ini adalah satu lagi cara bekerja dengan petunjuk.
>> Jadi ia akan bercakap tentang beberapa konsep
yang kita buat di dalam itu Penunjuk video, dan kami
akan menyembunyikan mereka sekarang, menganggap bahawa mereka sudah
semacam difahami.
Jadi itu hanya amaran yang adil jika anda lihat video ini
dan anda tidak melihat video petunjuk, ia mungkin jenis
terbang di atas kepala anda sedikit.
Dan jadi ia mungkin lebih baik menonton dalam perintah itu.
>> Oleh itu, kita telah melihat satu cara untuk bekerja dengan petunjuk,
yang kita mengisytiharkan berubah-ubah, dan kemudian kita
mengisytiharkan pembolehubah lain, penunjuk berubah-ubah, yang menunjuk kepadanya.
Oleh itu, kita telah membuat ubah dengan nama, kami telah
dicipta pembolehubah kedua dengan nama, dan kami menunjukkan bahawa pemboleh ubah kedua
pada yang pertama.
Ini jenis mempunyai masalah walaupun, kerana ia
memerlukan kita untuk mengetahui dengan tepat berapa banyak memori kami
akan memerlukan masa ini program kami disusun.
>> Kenapa begitu?
Kerana kita perlu berupaya untuk menamakan atau mengenal pasti semua pembolehubah mungkin
kita mungkin hadapi.
Kita mungkin mempunyai pelbagai yang mungkin dapat memegang banyak maklumat,
tetapi ia masih tidak betul-betul tepat mencukupi.
Bagaimana jika kita tidak tahu, bagaimana jika kita tidak tahu
berapa banyak yang kita perlu pada masa kompil?
Atau bagaimana jika program kami akan berjalan untuk masa yang lama,
menerima pelbagai pengguna data, dan kita tidak boleh benar-benar
menganggarkan sama ada kita berada akan memerlukan 1,000 unit?
>> Ia tidak seperti yang kita boleh katakan pada baris arahan
masukkan berapa banyak perkara anda fikir anda akan perlukan.
Nah bagaimana jika tekaan yang salah?
Peruntukan memori dinamik semacam membolehkan kami jalan yang
untuk mendapatkan sekitar masalah ini tertentu.
Dan cara ia ia adalah dengan menggunakan petunjuk.
>> Kita boleh menggunakan petunjuk untuk mendapat akses kepada dinamik
memori diperuntukkan, memori yang diperuntukkan sebagai program anda sedang berjalan.
Ia tidak diperuntukkan pada masa kompil.
Apabila anda dinamik memperuntukkan memori ia datang dari kolam
memori dikenali sebagai timbunan itu.
Sebelum ini semua memori kami telah telah bekerja dengan dalam perjalanan
telah datang dari kolam memori dikenali sebagai timbunan.
Cara yang baik untuk secara amnya menyimpan dalam kaedah mind-- dan ini
tidak selalu memegang benar, tetapi cukup banyak hampir
sentiasa memegang true-- ialah mana-mana kali anda memberikan nama pembolehubah ia
mungkin hidup dalam timbunan.
Dan bila-bila masa anda tidak memberi pembolehubah nama,
yang anda boleh lakukan dengan ingatan dinamik peruntukan, ia hidup dalam timbunan itu.
>> Sekarang saya jenis menyampaikan ini sebagai jika ada kedua-dua kolam ingatan.
Tetapi anda mungkin telah melihat ini rajah, yang biasanya
perwakilan apa memori kelihatan seperti,
dan kami tidak akan mengambil berat tentang semua barang-barang di bahagian atas dan bahagian bawah.
Apa yang kita mengambil berat tentang adalah bahagian ini dalam tengah sini, timbunan dan timbunan.
Seperti yang anda boleh lihat dengan melihat gambar rajah ini,
ini sebenarnya bukan dua kolam berasingan memori.
Ia adalah salah satu kolam dikongsi memori di mana anda mula pada yang demikian visual
anda bermula dari bawah dan mula mengisi
dari bahagian bawah dengan timbunan, dan anda mula di bahagian atas dan mula mengisi
dari atas ke bawah dengan timbunan itu.
Tetapi ia benar-benar adalah kolam sama, ia hanya
tempat yang berbeza, lokasi yang berbeza dalam ingatan yang diperuntukkan.
Dan anda boleh kehabisan memori dengan sama ada mempunyai
timbunan itu pergi sepanjang jalan ke bawah, atau mempunyai
timbunan pergi sepanjang jalan ke atas, atau mempunyai timbunan dan timbunan
bertemu antara satu sama lain.
Semua orang-orang boleh menjadi syarat yang menyebabkan program anda
kehabisan memori.
Jadi menyimpan bahawa dalam fikiran.
Apabila kita bercakap mengenai timbunan dan timbunan
kita benar-benar bercakap tentang sebahagian umum yang sama ingatan, hanya
bahagian yang berlainan memori itu.
>> Jadi bagaimana kita mendapatkan dinamik memori diperuntukkan di tempat pertama?
Bagaimana program kami mendapat memori kerana ia berjalan?
Well C menyediakan fungsi yang dipanggil malloc, allocator ingatan, yang
anda membuat panggilan kepada, dan anda lulus dalam berapa banyak bait memori yang anda mahu.
Jadi, jika program anda berjalan dan anda mahukan runtime integer,
anda mungkin mallock empat bait ingatan, malloc kurungan empat.
>> mallock akan melalui melihat melalui timbunan itu,
kerana kami dinamik memperuntukkan ingatan,
dan ia akan kembali kepada anda penunjuk kepada memori itu.
Ia tidak memberikan anda memory-- yang ia tidak memberikan nama,
ia memberi anda penunjuk kepadanya.
Dan itulah sebabnya mengapa lagi saya berkata bahawa ia adalah penting untuk mungkin
telah menonton video petunjuk yang sebelum kita terlalu jauh ke dalam ini.
Jadi malloc akan memberikan anda kembali penunjuk.
>> Jika mallock tidak boleh memberi apa-apa anda memori kerana anda telah habis,
ia akan memberikan anda kembali penunjuk null.
Adakah anda masih ingat apa yang berlaku jika kita cuba dereference penunjuk null?
Kami mengalami kesalahan seg, bukan?
Itu mungkin tidak baik.
>> Jadi setiap kali anda membuat panggilan malloc anda sentiasa, sentiasa
perlu menyemak sama ada atau tidak penunjuk ia memberikan anda kembali adalah batal.
Jika ia, anda perlu berakhir program anda kerana jika anda cuba dan dereference
penunjuk nol anda akan menderita kesalahan segmentasi
dan program anda akan kemalangan juga.
Jadi bagaimana kita statik mendapatkan integer?
>> int x.
Kita mungkin telah melakukan itu sekumpulan kali, bukan?
Ini mewujudkan pembolehubah yang dipanggil x yang hidup dalam timbunan.
Bagaimana kita secara dinamik mendapatkan integer?
Int bintang px sama malloc 4.
>> Atau lebih sesuai kita katakan px int bintang
sama saiz malloc int, hanya untuk membuang beberapa kurang
nombor ajaib sekitar program kami.
Ini akan mendapatkan untuk kita empat bait memori dari timbunan itu,
dan penunjuk yang kita dapat kembali ke ia dipanggil px.
Dan kemudian seperti yang kita ada dilakukan sebelum ini kita
boleh dereference px untuk mengakses memori itu.
Bagaimana kita mendapatkan integer dari pengguna?
Kita boleh mengatakan int x sama mendapatkan int.
Itu cukup mudah.
Bagaimana jika kita ingin membuat array daripada x pelampung yang hidup pada timbunan?
terapung stack_array-- itulah nama daripada array-- kami kurungan persegi x.
Yang akan mewujudkan untuk kita array daripada x pelampung yang hidup dalam timbunan.
Kita boleh membuat pelbagai terapung yang hidup pada timbunan itu juga.
Sintaks yang mungkin kelihatan sedikit lebih rumit,
tetapi kita boleh mengatakan apungan heap_array bintang sama
malloc x kali saiz apung.
Saya memerlukan ruang yang cukup untuk memegang x terapung nilai mata.
Jadi mengatakan saya perlu 100 terapung, terapung atau 1,000.
Jadi, dalam kes itu, ia akan menjadi 400 bait untuk 100 kereta berhias,
atau 4,000 bait untuk 1000 terapung, kerana setiap apungan mengambil
empat bait ruang.
>> Selepas berbuat demikian, saya boleh menggunakan persegi sintaks kurungan di heap_array.
Sama seperti saya lakukan pada stack_array, saya boleh mengakses unsur-unsur secara individu
menggunakan heap_array sifar, satu heap_array.
Tetapi ingat sebab kita boleh berbuat demikian adalah kerana nama pelbagai dalam C
adalah benar-benar penunjuk kepada Elemen pertama yang pelbagai ini.
Jadi hakikat bahawa kita mengisytiharkan pelbagai kereta berhias pada timbunan sini
sebenarnya agak mengelirukan.
Kami benar-benar berada dalam baris kedua kod terdapat
juga mewujudkan penunjuk kepada sebahagian daripada memori yang kemudian kita membuat kerja-kerja dengan.
>> Inilah masalah besar dengan dinamik diperuntukkan ingatan walaupun,
dan ini adalah mengapa ia benar-benar penting untuk membangunkan beberapa tabiat yang baik
apabila anda bekerja dengannya.
Tidak seperti statik diisytiharkan ingatan, ingatan anda
tidak secara automatik kembali ke sistem apabila fungsi selesai.
Jadi, jika kita mempunyai utama, dan utama panggilan fungsi
f, apabila f kemasan apa sahaja yang ia lakukan dan mengembalikan kawalan program
kembali ke utama, kesemua memori yang f yang digunakan diberikan kembali.
Ia boleh digunakan lagi oleh beberapa program lain,
atau beberapa fungsi lain yang mendapat dipanggil kemudian di dalam utama.
Ia boleh menggunakan memori yang sama berulang lagi.
>> Jika anda secara dinamik memperuntukkan memori walaupun
anda perlu memberitahu dengan jelas yang sistem yang anda selesai dengannya.
Ia akan memegang untuk anda, yang boleh membawa kepada masalah anda kehabisan
memori.
Dan sebenarnya kita kadang-kadang merujuk kepada ini sebagai kebocoran memori.
Dan kadang-kadang ini kebocoran memori sebenarnya boleh menjadi benar-benar dahsyat
untuk prestasi sistem.
>> Jika anda seorang pengguna internet yang kerap anda mungkin menggunakan pelayar web tertentu,
dan saya tidak akan menamakan nama-nama di sini, tetapi terdapat sesetengah pelayar web di luar sana
yang terkenal dengan sebenarnya mempunyai kebocoran memori yang tidak dapat ditetapkan.
Dan jika anda meninggalkan pelayar anda terbuka untuk tempoh yang sangat lama, hari
dan hari-hari, atau minggu, anda kadang-kadang mungkin perasan bahawa sistem anda
sedang berjalan benar-benar, benar-benar perlahan-lahan.
Dan sebab itu adalah bahawa pelayar telah memperuntukkan ingatan,
tetapi kemudian tidak kepada sistem bahawa ia dilakukan dengan ia.
Dan sebagainya yang meninggalkan memori kurang disediakan untuk semua program anda yang lain
untuk mempunyai untuk berkongsi, kerana anda leaking-- bahawa pelayar web
program bocor ingatan.
Bagaimana kita memberi ingatan kembali apabila kami sudah selesai dengan ia?
Well nasib baik ia adalah satu cara yang sangat mudah untuk melakukannya.
Kami hanya membebaskan.
Ada fungsi yang dipanggil percuma, ia menerima penunjuk kepada ingatan,
dan kami baik untuk pergi.
>> Jadi katakan kita berada di pertengahan program kami,
kita mahu malloc 50 aksara.
Kami mahu malloc pelbagai yang boleh mampu menampung 50 aksara.
Dan ketika kita mendapatkan penunjuk kembali ke itu, nama itu penunjuk adalah perkataan.
Kami melakukan apa sahaja yang kita akan lakukan dengan perkataan,
dan kemudian apabila kami dilakukan kita hanya membebaskan.
Dan sekarang kita telah kembali mereka 50 bait memori kembali kepada sistem.
Beberapa fungsi lain boleh menggunakannya.
Kami tidak perlu bimbang tentang mengalami memori kebocoran kerana kita telah dibebaskan perkataan.
Kami telah diberi ingatan kembali, jadi kami selesai bekerja dengannya.
Jadi, ada tiga peraturan keemasan yang perlu
diingat setiap kali anda berada dinamik memperuntukkan memori
dengan malloc.
Setiap blok memori yang anda malloc mesti dibebaskan
sebelum program anda selesai berjalan.
Kini sekali lagi, perkakas atau dalam IDE ini jenis berlaku untuk anda anyway
apabila atasmu, ini akan berlaku pula apabila program anda ditamatkan,
semua memori akan dikeluarkan.
Tetapi ia pengekodan umumnya baik amalan untuk biasa, apabila anda selesai,
membebaskan apa yang telah mallocd.
>> Yang berkata, perkara-perkara yang anda telah mallocd perlu dibebaskan.
Jika anda statik mengisytiharkan integer, int x koma bertitik,
yang hidup pada timbunan, anda jangan kemudian mahu membebaskan x.
Jadi hanya perkara yang anda telah mallocd perlu dibebaskan.
>> Dan akhir sekali, tidak sesuatu yang percuma dua kali.
Yang boleh membawa kepada lain keadaan pelik.
Jadi semua yang anda telah mallocd perlu dibebaskan.
Hanya perkara yang anda telah malloc perlu dibebaskan.
Dan tidak melakukan sesuatu yang percuma dua kali.
>> Jadi mari kita pergi melalui contoh di sini apa yang sesetengah dinamik diperuntukkan
memori mungkin kelihatan seperti bercampur-campur dengan beberapa ingatan statik.
Apa yang mungkin berlaku di sini?
Lihat jika anda boleh mengikuti bersama-sama dan meneka apa yang
akan berlaku seperti yang kita pergi melalui semua ini baris kod.
>> Oleh itu, kita mengatakan int m.
Apa yang berlaku di sini?
Nah ini adalah agak mudah.
Saya mencipta satu pembolehubah integer dipanggil m.
Saya warna hijau, kerana itulah warna
yang saya gunakan apabila saya bercakap tentang pembolehubah integer.
Ia adalah sebuah kotak.
Ia dipanggil m, dan anda boleh integer kedai di dalamnya.
>> Bagaimana jika saya kemudian berkata int bintang?
Baik yang agak sama.
Saya mewujudkan kotak yang dikenali sebagai.
Ia mampu int pegangan bintang, petunjuk kepada integer.
Jadi, saya mewarna ia hijau-ish juga.
>> Saya tahu ia mempunyai sesuatu kaitan dengan integer,
tetapi ia sendiri adalah integer.
Tetapi ia cukup banyak idea yang sama.
Saya telah membuat sebuah kotak.
Kedua-dua hak ini kini hidup dalam timbunan.
Saya telah memberikan mereka kedua-dua nama.
>> int bintang b sama saiz malloc int.
Yang ini mungkin sedikit rumit.
Mengambil kedua dan berfikir tentang apa yang anda inginkan berlaku pada gambarajah ini.
int bintang b sama saiz malloc int.
>> Nah ini bukan sahaja mewujudkan satu kotak.
Ini sebenarnya mewujudkan dua kotak.
Dan hubungan, ia juga menetapkan titik dalam hubungan.
Kami telah diperuntukkan satu blok memori pada timbunan itu.
Perhatikan bahawa kotak atas kanan terdapat tidak mempunyai nama.
>> Kami mallocd ia.
Ia wujud pada timbunan itu.
Tetapi b mempunyai nama.
Ia adalah satu pembolehubah penunjuk dipanggil b.
Yang hidup dalam timbunan.
>> Jadi ia adalah sekeping memori yang menunjukkan satu sama lain.
b mengandungi alamat itu blok ingatan.
Ia tidak mempunyai nama yang sebaliknya.
Tetapi ia menjurus kepadanya.
Oleh itu, apabila kita katakan int bintang b sama saiz malloc int, yang di sana,
bahawa anak panah yang muncul pada sampingan di sana, bahawa perkara keseluruhan,
Saya akan mempunyai ia kelihatan sekali lagi, apa yang berlaku.
Semua itu berlaku dalam yang baris kod.
Sekarang kita akan mendapat sedikit lebih terus-terang lagi.
yang sama Ampersand m.
Adakah anda masih ingat apa yang sama Ampersand m adalah?
Nah itu yang mendapat alamat m.
Atau meletakkan lebih rajah, satu mata kepada m.
>> yang sama b.
OK jadi di sini adalah satu sama lain.
A sama dengan b.
Apa yang akan berlaku diagram di masa ini?
>> Juga ingat bahawa kerja-kerja pengendali tugasan
dengan memberi nilai di hak untuk nilai di sebelah kiri.
Jadi, daripada yang menunjuk ke m, sekarang menunjuk ke tempat yang sama yang b mata.
yang tidak menunjukkan b, yang menunjukkan di mana b mata.
>> Jika tajamnya untuk b yang akan telah menjadi sama Ampersand b.
Tetapi sebaliknya yang sama b hanya bermakna dan b adalah sekarang
menunjuk ke alamat yang sama, kerana bahagian dalam b hanya alamat.
Dan kini di dalam adalah alamat yang sama.
m sama dengan 10, mungkin yang Perkara yang paling mudah
kita lakukan pada sedikit.
Meletakkan 10 di dalam kotak.
Star b sama dengan m campur 2, ingat dari apa bintang petunjuk video kami b bermakna.
Kami akan dereference b dan meletakkan beberapa nilai di lokasi itu ingatan.
Dalam kes ini 12.
>> Jadi, apabila kita dereference titik ingat kita hanya melakukan perjalanan ke bawah anak panah.
Atau meletakkan cara lain, kami pergi ke alamat memori
dan kami memanipulasi ia dalam beberapa cara.
Kami meletakkan beberapa nilai di sana.
Di bintang kes ini b sama dengan m campur 2 sahaja
pergi kepada pembolehubah yang ditunjukkan oleh b, pergi kepada memori yang ditunjukkan oleh b,
dan meletakkan m campur 2 di sana, 12.
>> Sekarang saya membebaskan b.
Apa yang berlaku apabila saya membebaskan b?
Ingat apa yang saya katakan cara percuma.
Apa yang saya katakan apabila saya membebaskan b?
>> Saya selesai bekerja dengannya, bukan?
Saya pada dasarnya melepaskan memori.
Saya memberikan kembali kepada sistem.
Saya tidak memerlukan ini lagi adalah apa yang saya memberitahu mereka, OK?
>> Sekarang jika saya katakan bintang bersamaan 11 anda mungkin boleh
telah memberitahu sesuatu yang tidak baik yang akan berlaku di sini, bukan?
Dan sesungguhnya jika saya cuba bahawa saya mungkin akan mengalami kesalahan segmentasi.
Kerana sekarang, walaupun sebelum ini bahawa sebahagian memori
adalah sesuatu yang saya mempunyai akses kepada, pada ketika ini
sekarang saya mengakses memori yang bukan undang-undang bagi saya untuk mengakses.
>> Dan seperti yang kita akan mungkin ingat, apabila kita mengakses memori
bahawa kita tidak sepatutnya menyentuh, itulah punca yang paling biasa
segmentasi yang kesalahan. Dan supaya program saya
akan berlanggar jika saya cuba untuk melakukan ini.
Jadi sekali lagi ia adalah satu idea yang baik untuk mendapatkan yang baik Tabiat amalan dan baik berakar umbi
apabila bekerja dengan malloc dan bebas, supaya anda tidak mengalami segmentasi
kesalahan, dan yang anda gunakan anda diperuntukkan secara dinamik
memori bertanggungjawab.
>> Saya Doug Lloyd ini adalah CS50.