Saya telah belajar C ++ dan saya kesulitan memahami nol. Secara khusus, tutorial yang saya baca menyebutkan melakukan "cek kosong", tapi saya tidak yakin apa artinya atau mengapa itu perlu.
- Apa itu null?
- Apa artinya "memeriksa null"?
- Apakah saya selalu perlu memeriksa nol?
Setiap contoh kode akan sangat dihargai.
Jawaban:
Dalam C dan C ++, pointer secara inheren tidak aman, yaitu, ketika Anda melakukan dereferensi pointer, itu adalah tanggung jawab Anda sendiri untuk memastikan itu menunjuk ke suatu tempat yang valid; ini adalah bagian dari "manajemen memori manual" (bukan skema manajemen memori otomatis yang diterapkan dalam bahasa seperti Java, PHP, atau .NET runtime, yang tidak akan memungkinkan Anda membuat referensi yang tidak valid tanpa usaha yang cukup).
Solusi umum yang menangkap banyak kesalahan adalah dengan mengatur semua pointer yang tidak menunjuk ke apa pun sebagai
NULL
(atau, dalam C ++ yang benar,0
), dan memeriksa untuk itu sebelum mengakses pointer. Secara khusus, itu adalah praktik umum untuk menginisialisasi semua pointer ke NULL (kecuali Anda sudah memiliki sesuatu untuk mengarahkan mereka ketika Anda mendeklarasikannya), dan mengaturnya ke NULL ketika Andadelete
ataufree()
mereka (kecuali mereka keluar dari ruang lingkup segera setelah itu). Contoh (dalam C, tetapi juga valid C ++):Versi yang lebih baik:
Tanpa tanda centang nol, meneruskan pointer NULL ke fungsi ini akan menyebabkan segfault, dan tidak ada yang dapat Anda lakukan - OS hanya akan membunuh proses Anda dan mungkin core-dump atau pop up dialog laporan kerusakan. Dengan tanda centang nol di tempat, Anda dapat melakukan penanganan kesalahan yang tepat dan memulihkan dengan anggun - perbaiki sendiri masalahnya, batalkan operasi saat ini, tulis entri log, beri tahu pengguna, apa pun yang sesuai.
sumber
Jawaban lain cukup banyak mencakup pertanyaan Anda. Pemeriksaan nol dilakukan untuk memastikan bahwa pointer yang Anda terima benar-benar menunjuk ke instance yang valid dari suatu tipe (objek, primitif, dll.).
Saya akan menambahkan saran saya sendiri di sini. Hindari cek nol. :) Null memeriksa (dan bentuk-bentuk lain dari Pemrograman Defensif) mengacaukan kode, dan benar-benar membuatnya lebih rentan kesalahan daripada teknik penanganan kesalahan lainnya.
Teknik favorit saya ketika datang ke pointer objek adalah dengan menggunakan pola Obyek Null . Itu berarti mengembalikan (pointer - atau bahkan lebih baik, referensi ke) array kosong atau daftar bukan nol, atau mengembalikan string kosong ("") bukannya nol, atau bahkan string "0" (atau sesuatu yang setara dengan "tidak ada" "dalam konteks) tempat Anda mengharapkannya diuraikan menjadi integer.
Sebagai bonus, berikut ini adalah sesuatu yang mungkin tidak Anda ketahui tentang null pointer, yang (pertama kali secara resmi) diimplementasikan oleh CAR Hoare untuk bahasa Algol W pada tahun 1965.
sumber
Nilai penunjuk nol mewakili "tempat" yang didefinisikan dengan baik; itu adalah nilai pointer yang tidak valid yang dijamin untuk membandingkan tidak sama dengan nilai pointer lainnya. Mencoba untuk melakukan dereferensi hasil pointer nol dalam perilaku tidak terdefinisi, dan biasanya akan menyebabkan kesalahan runtime, jadi Anda ingin memastikan pointer tidak NULL sebelum mencoba melakukan dereferensi. Sejumlah fungsi pustaka C dan C ++ akan mengembalikan pointer nol untuk menunjukkan kondisi kesalahan. Misalnya, fungsi pustaka
malloc
akan mengembalikan nilai pointer nol jika tidak dapat mengalokasikan jumlah byte yang telah diminta, dan mencoba mengakses memori melalui pointer itu (biasanya) akan menyebabkan kesalahan runtime:Jadi kita perlu memastikan
malloc
panggilan berhasil dengan memeriksa nilaip
terhadap NULL:Sekarang, tunggu sebentar, ini akan sedikit bergelombang.
Ada nilai pointer nol dan konstanta pointer nol , dan keduanya tidak harus sama. Nilai penunjuk nol adalah nilai apa pun yang digunakan arsitektur dasar untuk mewakili "tempat". Nilai ini mungkin 0x00000000, atau 0xFFFFFFFF, atau 0xDEADBEEF, atau sesuatu yang sama sekali berbeda. Jangan berasumsi bahwa pointer nol nilai selalu 0.
Konstanta penunjuk nol , OTOH, selalu merupakan ekspresi integral bernilai 0. Sejauh menyangkut kode sumber Anda , 0 (atau ekspresi integral apa pun yang bernilai 0) mewakili penunjuk nol. Baik C dan C ++ mendefinisikan makro NULL sebagai konstanta penunjuk nol. Ketika kode Anda dikompilasi, null pointer konstan akan diganti dengan nol pointer yang sesuai nilai dalam kode mesin yang dihasilkan.
Perlu diketahui juga bahwa NULL hanyalah salah satu dari banyak nilai pointer yang mungkin tidak valid ; jika Anda mendeklarasikan variabel penunjuk otomatis tanpa menginisialisasi secara eksplisit, seperti
nilai awalnya disimpan dalam variabel tidak tentu , dan mungkin tidak sesuai dengan alamat memori yang valid atau dapat diakses. Sayangnya, tidak ada cara (portabel) untuk mengetahui apakah nilai pointer non-NULL valid atau tidak sebelum mencoba menggunakannya. Jadi jika Anda berurusan dengan pointer, biasanya ide yang baik untuk secara eksplisit menginisialisasi mereka ke NULL ketika Anda mendeklarasikannya, dan untuk mengaturnya ke NULL ketika mereka tidak secara aktif menunjuk ke apa pun.
Perhatikan bahwa ini lebih merupakan masalah dalam C daripada C ++; C ++ idiomatis seharusnya tidak menggunakan pointer sebanyak itu.
sumber
Ada beberapa metode, semua pada dasarnya melakukan hal yang sama.
cek nol (periksa apakah pointernya nol), versi A
cek nol, versi B
cek nol, versi C
Dari ketiganya, saya lebih suka menggunakan cek pertama karena secara eksplisit memberi tahu pengembang masa depan apa yang Anda coba periksa DAN itu membuat jelas bahwa Anda diharapkan foo menjadi pointer.
sumber
Kamu tidak. Satu-satunya alasan untuk menggunakan pointer di C ++ adalah karena Anda secara eksplisit menginginkan keberadaan null pointer; selain itu, Anda dapat mengambil referensi, yang secara semantik lebih mudah digunakan dan menjamin non-null.
sumber
export
) dan semua fitur pustaka C ++ 03 dan TR1 dan sebagian besar C ++ 11.Jika Anda tidak memeriksa nilai NULL, khususnya, jika itu adalah pointer ke struct, Anda mungkin bertemu dengan kerentanan keamanan - Nere pointer dereference. NULL pointer dereference dapat menyebabkan beberapa kerentanan keamanan serius lainnya seperti buffer overflow, kondisi ras ... yang dapat memungkinkan penyerang mengendalikan komputer Anda.
Banyak vendor perangkat lunak seperti Microsoft, Oracle, Adobe, Apple ... merilis patch perangkat lunak untuk memperbaiki kerentanan keamanan ini. Saya pikir Anda harus memeriksa nilai NULL dari setiap pointer :)
sumber