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