[MUSIC PLAYING] Doug LLOYD: OK jadi saran sebelum mulai di sini. Jika Anda belum menonton video di pointer Anda mungkin ingin melakukannya pertama. Karena video ini adalah satu lagi cara bekerja dengan pointer. Jadi itu akan berbicara tentang beberapa konsep bahwa kita menutupi dalam pointer video, dan kami akan mengabaikan mereka sekarang, dengan asumsi bahwa mereka sudah semacam dipahami. Jadi itu hanya adil peringatan Anda bahwa jika Anda melihat video ini dan Anda belum melihat pointer video, itu mungkin semacam terbang di atas kepala Anda sedikit. Dan jadi mungkin akan lebih baik untuk menonton dalam urutan itu. Jadi kita telah melihat satu cara untuk bekerja dengan pointer, yang kita mendeklarasikan variabel, dan kemudian kita mendeklarasikan variabel lain, pointer variabel, yang menunjuk ke itu. Jadi kami telah membuat variabel dengan nama, kami sudah menciptakan variabel kedua dengan nama, dan kami menunjukkan bahwa variabel kedua pada saat itu pertama. Ini semacam memiliki masalah meskipun, karena mengharuskan kita untuk tahu persis berapa banyak memori kami akan membutuhkan saat ini program kami dikompilasi. Kenapa itu? Karena kita harus mampu untuk nama atau mengidentifikasi semua variabel yang mungkin mungkin kita hadapi. Kita mungkin memiliki sebuah array yang mungkin mampu menahan banyak informasi, tapi masih tidak persis cukup tepat. Bagaimana jika kita tidak tahu, bagaimana jika kita tidak tahu berapa banyak kita harus pada waktu kompilasi? Atau bagaimana jika program kami akan menjalankan untuk waktu yang sangat lama, menerima berbagai pengguna data, dan kita tidak bisa benar-benar memperkirakan apakah kami akan membutuhkan 1.000 unit? Ini tidak seperti yang kita bisa mengatakan pada baris perintah masukkan berapa banyak item Anda pikir Anda butuhkan. Nah bagaimana jika tebakan itu salah? Alokasi memori dinamis semacam memungkinkan kita jalan untuk mengatasi masalah khusus ini. Dan cara itu melakukannya adalah dengan menggunakan pointer. Kita bisa menggunakan pointer ke mendapatkan akses untuk secara dinamis dialokasikan memori, memori yang dialokasikan sebagai program anda berjalan. Ini tidak dialokasikan pada waktu kompilasi. Ketika Anda secara dinamis mengalokasikan memori itu berasal dari kolam renang memori yang dikenal sebagai tumpukan. Sebelumnya semua memori kita sudah telah bekerja dengan di kursus telah datang dari kolam renang memori yang dikenal sebagai stack. Cara yang baik untuk umum tetap mind-- dan ini aturan tidak selalu berlaku, tapi cukup banyak hampir selalu memegang true-- adalah bahwa setiap kali Anda memberikan nama variabel itu mungkin hidup di stack. Dan setiap kali Anda tidak memberi nama variabel, yang dapat Anda lakukan dengan memori dinamis alokasi, ia hidup di heap. Sekarang aku jenis menyajikan ini sebagai jika ada dua kolam memori. Tapi Anda mungkin telah melihat ini diagram, yang umumnya representasi dari apa yang tampak seperti memori, dan kami tidak akan peduli tentang semua hal-hal di atas dan bawah. Apa yang kita pedulikan adalah bagian ini di tengah di sini, tumpukan dan tumpukan. Seperti yang dapat Anda lihat dengan melihat diagram ini, ini sebenarnya bukan dua kolam terpisah dari memori. Itu salah satu kolam bersama memori di mana Anda mulai, dalam hal ini visual yang Anda mulai di bagian bawah dan mulai mengisi dari bawah dengan tumpukan, dan Anda mulai dari atas dan mulai mengisi dari atas ke bawah dengan tumpukan. Tapi itu benar-benar adalah kolam renang yang sama, hanya saja tempat yang berbeda, lokasi yang berbeda dalam memori yang dialokasikan. Dan Anda dapat kehabisan memori dengan baik memiliki tumpukan pergi semua jalan ke bawah, atau memiliki stack pergi semua jalan ke atas, atau memiliki tumpukan dan tumpukan bertemu satu sama lain. Semua dari mereka dapat menjadi kondisi yang menyebabkan program Anda kehabisan memori. Jadi ingatlah bahwa dalam pikiran. Ketika kita berbicara tentang tumpukan dan tumpukan kita benar-benar berbicara tentang sepotong umum yang sama dari memori, hanya bagian yang berbeda dari memori itu. Jadi bagaimana kita bisa secara dinamis memori yang dialokasikan di tempat pertama? Bagaimana program kami mendapatkan memori itu berjalan? Nah C menyediakan fungsi yang disebut malloc, pengalokasi memori, yang Anda membuat panggilan ke, dan Anda lulus dalam berapa banyak byte memori yang Anda inginkan. Jadi jika program anda berjalan dan Anda ingin runtime integer, Anda mungkin Mallock empat byte memori, malloc kurung empat. Mallock akan melalui melihat melalui tumpukan, karena kita dinamis mengalokasikan memori, dan akan kembali kepada Anda pointer ke memori itu. Ini tidak memberikan memory-- yang tidak memberikan nama, memberikan Anda pointer untuk itu. Dan jadi itu sebabnya saya katakan lagi bahwa penting untuk mungkin telah menyaksikan video yang pointer sebelum kita masuk terlalu jauh ke dalam ini. Jadi malloc akan memberikan kembali pointer. Jika Mallock tidak bisa memberikan apapun memori karena Anda telah habis, itu akan memberi Anda kembali pointer null. Apakah Anda ingat apa yang terjadi jika kita mencoba dan dereference pointer nol? Kita menderita kesalahan seg, kan? Itu mungkin tidak baik. Jadi setiap kali Anda membuat panggilan untuk malloc Anda selalu, selalu perlu memeriksa apakah atau tidak pointer itu memberi Anda kembali adalah null. Jika ya, Anda perlu untuk mengakhiri program Anda karena jika Anda mencoba dan dereference pointer nol Anda akan menderita kesalahan segmentasi dan program anda adalah akan crash pula. Jadi bagaimana kita statis mendapatkan integer? int x. Kita mungkin telah melakukan itu beberapa kali, kan? Hal ini menciptakan sebuah variabel yang disebut x yang hidup di stack. Bagaimana kita dinamis mendapatkan integer? Int bintang px sama malloc 4. Atau lebih tepat kita akan mengatakan int bintang px sama dengan ukuran malloc dari int, hanya untuk membuang beberapa lebih sedikit angka ajaib di sekitar program kami. Ini akan memperoleh bagi kita empat byte memori dari tumpukan, dan pointer kita mendapatkan kembali ke itu disebut px. Dan kemudian hanya karena kami sudah dilakukan sebelumnya kami bisa dereference px untuk mengakses memori itu. Bagaimana kita mendapatkan bilangan bulat dari pengguna? Kita dapat mengatakan int x sama mendapatkan int. Itu cukup sederhana. Bagaimana jika kita ingin membuat sebuah array dari x mengapung yang hidup di stack? mengapung stack_array-- itu nama kami array-- kurung x. Yang akan menciptakan bagi kita sebuah array dari x mengapung yang hidup di stack. Kita dapat membuat array mengapung yang hidup di heap, juga. Sintaks mungkin terlihat sedikit lebih rumit, tapi kita dapat mengatakan mengapung Bintang heap_array sama malloc x kali ukuran float. Saya perlu cukup ruang untuk menahan x nilai floating point. Jadi mengatakan saya perlu 100 mengapung, atau 1.000 mengapung. Jadi dalam hal ini akan 400 byte untuk 100 mengapung, atau 4.000 byte untuk 1.000 mengapung, karena setiap mengapung mengambil empat byte ruang. Setelah melakukan hal ini saya dapat menggunakan sintaks braket persegi di heap_array. Sama seperti saya akan di stack_array, saya dapat mengakses elemen individual menggunakan heap_array nol, heap_array satu. Tapi ingat alasan kita bisa melakukan itu adalah karena nama array di C benar-benar pointer ke elemen pertama yang array. Sehingga fakta bahwa kita mendeklarasikan array mengapung di stack sini sebenarnya agak menyesatkan. Kami benar-benar berada di baris kedua kode ada juga menciptakan pointer ke sepotong memori yang kemudian kita melakukan beberapa pekerjaan dengan. Inilah masalah besar dengan dialokasikan secara dinamis memori meskipun, dan ini adalah mengapa itu benar-benar penting untuk mengembangkan beberapa kebiasaan yang baik ketika Anda bekerja dengan itu. Tidak seperti statis dideklarasikan memori, memori Anda tidak secara otomatis kembali ke sistem ketika fungsi Anda dilakukan. Jadi jika kita memiliki utama, dan utama panggilan fungsi f, ketika f selesai apa yang dilakukannya dan mengembalikan kontrol program kembali ke utama, semua memori yang f digunakan diberikan kembali. Hal ini dapat digunakan lagi oleh beberapa program lain, atau beberapa fungsi lain yang dipanggil nanti di utama. Hal ini dapat menggunakan memori yang sama lagi. Jika Anda secara dinamis mengalokasikan memori meskipun Anda harus secara eksplisit memberitahu sistem yang sedang Anda lakukan dengan itu. Ini akan terus ke atasnya untuk Anda, yang bisa menyebabkan masalah Anda kehabisan memori. Dan pada kenyataannya kita kadang-kadang merujuk ini sebagai kebocoran memori. Dan kadang-kadang kebocoran memori ini benar-benar dapat menjadi benar-benar dahsyat untuk kinerja sistem. Jika Anda adalah pengguna internet sering Anda mungkin menggunakan web browser tertentu, dan saya tidak akan menyebut nama di sini, tapi ada beberapa web browser di luar sana yang terkenal karena benar-benar memiliki kebocoran memori yang tidak bisa diperbaiki. Dan jika Anda meninggalkan browser Anda terbuka untuk jangka waktu yang sangat lama, hari dan hari, atau minggu, Anda kadang-kadang mungkin melihat bahwa sistem Anda adalah berjalan benar-benar perlahan. Dan alasan untuk itu adalah bahwa browser telah mengalokasikan memori, tapi kemudian tidak mengatakan sistem bahwa hal itu dilakukan dengan itu. Dan sehingga meninggalkan sedikit memori tersedia untuk semua program Anda yang lain harus berbagi, karena Anda leaking-- yang browser web Program bocor memori. Bagaimana kita memberikan memori kembali ketika kita sudah selesai dengan itu? Nah untungnya itu adalah cara yang sangat mudah untuk melakukannya. Kami hanya membebaskan itu. Ada fungsi yang disebut gratis, ia menerima pointer ke memori, dan kami baik untuk pergi. Jadi katakanlah kita berada di tengah program kami, kami ingin malloc 50 karakter. Kami ingin malloc array yang dapat mampu memegang 50 karakter. Dan ketika kita mendapatkan pointer kembali ke itu, nama itu pointer adalah kata. Kami melakukan apa kami akan melakukan dengan kata, dan kemudian ketika kami dilakukan kita hanya membebaskan itu. Dan sekarang kami telah kembali mereka 50 byte memori kembali ke sistem. Beberapa fungsi lain dapat menggunakannya. Kami tidak perlu khawatir tentang menderita kebocoran memori karena kita telah dibebaskan kata. Kami telah memberikan memori kembali, jadi kita sudah selesai bekerja dengan itu. Jadi ada tiga aturan emas yang seharusnya diingat setiap kali Anda dinamis mengalokasikan memori dengan malloc. Setiap blok memori yang Anda malloc harus dibebaskan sebelum program selesai berjalan. Sekarang lagi, dalam alat atau di IDE ini semacam terjadi untuk Anda juga ketika you-- ini akan terjadi pula ketika program Anda dihentikan, semua memori akan dirilis. Tapi itu coding umumnya baik praktek untuk selalu, ketika Anda sudah selesai, membebaskan apa yang telah Anda mallocd. Yang mengatakan, hanya hal-hal yang Anda sudah mallocd harus dibebaskan. Jika Anda statis mendeklarasikan integer, int x semi-colon, yang hidup di stack, Anda tidak kemudian ingin membebaskan x. Sehingga hanya hal-hal yang Anda sudah mallocd harus dibebaskan. Dan terakhir, tidak sesuatu yang gratis dua kali. Yang dapat menyebabkan situasi yang aneh lagi. Jadi segala sesuatu yang Anda sudah mallocd harus dibebaskan. Hanya hal-hal yang Anda sudah malloc harus dibebaskan. Dan tidak sesuatu yang gratis dua kali. Jadi mari kita pergi melalui contoh di sini dari apa yang beberapa dialokasikan secara dinamis memori mungkin terlihat seperti campuran dengan beberapa memori statis. Apa yang mungkin terjadi di sini? Lihat jika Anda dapat mengikuti bersama dan menebak apa akan terjadi seperti yang kita pergi melalui semua baris kode. Jadi kita katakan int m. Apa yang terjadi di sini? Nah ini cukup sederhana. Saya membuat sebuah variabel integer disebut m. Aku warna hijau, karena itulah warna yang saya gunakan ketika saya sedang berbicara tentang variabel integer. Ini sebuah kotak. Ini disebut m, dan Anda dapat toko bilangan bulat di dalamnya. Bagaimana jika saya kemudian mengatakan bintang int a? Nah itu sangat mirip. Aku menciptakan sebuah kotak yang disebut. Ini mampu memegang int bintang, pointer ke bilangan bulat. Jadi aku mewarnai hijau-ish juga. Aku tahu itu ada hubungannya dengan integer, tapi itu tidak sendiri integer. Tapi itu cukup banyak ide yang sama. Saya telah membuat sebuah kotak. Kedua hak ini sekarang tinggal di stack. Saya telah memberi mereka kedua nama. int bintang b sama dengan ukuran malloc dari int. Yang satu ini mungkin sedikit rumit. Mengambil kedua dan berpikir tentang apa yang Anda harapkan terjadi pada diagram ini. int bintang b sama dengan ukuran malloc dari int. Nah ini tidak hanya membuat satu kotak. Ini benar-benar menciptakan dua kotak. Dan mengikat, itu juga menetapkan titik dalam suatu hubungan. Kami telah dialokasikan satu blok memori di heap. Perhatikan bahwa kotak kanan atas ada tidak memiliki nama. Kami mallocd itu. Ini ada di heap. Tapi b memiliki nama. Ini adalah variabel pointer yang disebut b. Yang hidup di stack. Jadi itu bagian dari memori yang menunjuk ke satu sama lain. b berisi alamat dari blok memori. Ia tidak memiliki nama sebaliknya. Tapi itu menunjukkan untuk itu. Jadi ketika kita mengatakan int bintang b sama Ukuran malloc dari int, bahwa di sana, bahwa panah yang muncul pada sisi kanan ada, yang semuanya, Aku akan tampak lagi, adalah apa yang terjadi. Semua itu terjadi di bahwa baris kode. Sekarang kita akan mendapatkan sedikit lebih mudah lagi. a sama dengan ampersand m. Apakah Anda ingat apa sama dengan ampersand m adalah? Nah itu mendapat alamat m ini. Atau menempatkan lebih diagram, poin untuk m. a sama b. OK jadi inilah satu lagi. Sebuah sama b. Apa yang akan terjadi diagram kali ini? Nah ingat bahwa karya operator penugasan dengan menetapkan nilai pada hak untuk nilai di sebelah kiri. Jadi, bukannya menunjuk ke m, sekarang menunjuk ke tempat yang sama yang b poin. a tidak menunjuk ke b, a menunjukkan di mana b poin. Jika menunjuk ke b yang akan telah sama ampersand b. Tapi bukan sama b hanya berarti dan b sekarang menunjuk ke alamat yang sama, karena dalam b hanya sebuah alamat. Dan sekarang dalam adalah alamat yang sama. m sama dengan 10, mungkin kebanyakan hal sederhana kami lakukan di sedikit. Menempatkan 10 di dalam kotak. Bintang b sama dengan m ditambah 2, ingat dari pointer video kami star apa b berarti. Kita akan dereference b dan put beberapa nilai di lokasi memori. Dalam hal ini 12. Jadi ketika kita dereference titik mengingat kami hanya melakukan perjalanan ke panah. Atau dengan kata lain, kita pergi ke alamat memori dan kami memanipulasinya dalam beberapa cara. Kami menempatkan beberapa nilai di sana. Dalam hal ini bintang b sama m ditambah 2 hanya pergi ke variabel yang ditunjuk oleh b, pergi ke memori yang ditunjuk oleh b, dan menempatkan m ditambah 2 di sana, 12. Sekarang saya bebas b. Apa yang terjadi ketika saya bebas b? Ingat apa yang saya katakan bebas berarti. Apa yang saya katakan ketika saya bebas b? Aku sudah selesai bekerja dengan itu, kan? Saya pada dasarnya menyerah memori. Aku memberikannya kembali ke sistem. Saya tidak perlu ini lagi adalah apa yang saya mengatakan kepada mereka, OK? Sekarang jika saya mengatakan bintang sama 11 mungkin Anda dapat sudah mengatakan bahwa sesuatu yang buruk yang akan terjadi di sini, kan? Dan memang jika saya mencoba bahwa saya mungkin akan menderita kesalahan segmentasi. Karena sekarang, meskipun sebelumnya bahwa sepotong memori adalah sesuatu yang saya punya akses ke, pada titik ini sekarang saya mengakses memori yang tidak sah bagi saya untuk mengakses. Dan seperti yang kita mungkin akan ingat, ketika kita mengakses memori bahwa kita tidak seharusnya menyentuh, itulah penyebab paling umum segmentasi sebuah kesalahan. Dan program saya akan crash jika saya mencoba untuk melakukan hal ini. Jadi sekali lagi itu adalah ide yang baik untuk mendapatkan yang baik praktek dan kebiasaan yang baik tertanam ketika bekerja dengan malloc dan bebas, sehingga Anda tidak menderita segmentasi kesalahan, dan bahwa Anda menggunakan Anda dialokasikan secara dinamis memori bertanggung jawab. Aku Doug Lloyd ini CS50.