[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.