Persoalan yang kelihatan mudah tentang apa yang berlaku apabila anda meminta komputer untuk mengagihkan sifar bait memori telah mencetuskan perdebatan sengit dalam kalangan pengaturcara. Teka-teki teknikal ini mendedahkan isu yang lebih mendalam tentang piawaian perisian, keserasian sistem, dan cabaran menulis kod yang mudah alih.
Apabila pengaturcara memanggil malloc(0) - satu fungsi yang meminta sifar bait memori - sistem komputer yang berbeza bertindak balas dengan cara yang sama sekali berbeza. Sesetengah sistem mengembalikan nilai null khas yang menunjukkan tiada apa yang diagihkan, manakala yang lain menyediakan alamat memori unik yang menunjuk kepada... tiada apa-apa. Ketidakkonsistenan ini telah menyebabkan kegagalan perisian dunia sebenar dan terus mengecewakan pembangun berpuluh tahun selepas tingkah laku ini mula-mula dipiawaikan.
Piawaian Membenarkan Dua Tingkah Laku Berbeza
Punca masalah ini terletak pada cara piawaian pengaturcaraan ditulis. Kedua-dua piawaian bahasa pengaturcaraan C dan spesifikasi POSIX dengan sengaja membenarkan malloc(0) berkelakuan dalam dua cara: sama ada mengembalikan null atau mengembalikan penunjuk unik yang tidak boleh digunakan untuk mengakses memori. Keputusan ini dibuat untuk mengelakkan kerosakan pelaksanaan perisian sedia ada yang sudah berfungsi secara berbeza.
Perbincangan komuniti mendedahkan bahawa tingkah laku dwi ini mencipta masalah praktikal. Apabila kod yang sama dijalankan pada sistem yang berbeza, ia mungkin berfungsi dengan sempurna pada satu mesin tetapi gagal secara bencana pada yang lain. Seorang pembangun berkongsi pengalaman mereka menyelenggara perisian yang gagal khususnya pada sistem AIX kerana malloc(0) mengembalikan null apabila kod mengharapkan penunjuk yang sah.
Pilihan Tingkah Laku malloc(0) Standard C:
- Pilihan 1: Mengembalikan penunjuk NULL (menunjukkan tiada peruntukan)
- Pilihan 2: Mengembalikan penunjuk bukan- NULL yang unik (tidak boleh dirujuk)
- Keperluan: Jika bukan- NULL , setiap panggilan mesti mengembalikan alamat yang unik
- Piawaian: Ditakrifkan dalam spesifikasi C89 , C99 , dan POSIX
Keperluan Penunjuk Unik Mencipta Kerumitan
Apabila sistem memilih untuk mengembalikan penunjuk yang sah untuk pengagihan sifar bait, mereka mesti memastikan setiap panggilan menghasilkan alamat yang unik. Keperluan ini, yang dimandatkan oleh piawaian, memaksa pengagih memori untuk menjejaki penunjuk khas ini walaupun mereka menunjuk kepada tiada memori yang boleh digunakan.
Setiap pengagihan sedemikian hendaklah menghasilkan penunjuk kepada objek yang terpisah daripada mana-mana objek lain.
Keperluan keunikan ini telah membawa kepada pelaksanaan yang kreatif tetapi bermasalah. Sesetengah sistem terbenam lama mengembalikan nilai malar -1 untuk semua panggilan malloc(0), yang melanggar piawaian tetapi memenuhi keperluan khusus mereka. Walau bagaimanapun, pendekatan sedemikian boleh merosakkan kod yang menggunakan penunjuk sebagai kunci dalam struktur data, di mana alamat pendua menyebabkan perlanggaran yang tidak dijangka.
Kesan Dunia Sebenar Terhadap Pembangunan Perisian
Ketidakkonsistenan malloc(0) mempengaruhi lebih daripada sekadar perbincangan akademik. Pembangun yang bekerja dengan bekas generik, perpustakaan pengurusan memori, dan perisian merentas platform mesti mengambil kira kepelbagaian ini. Sesetengah fungsi dalam perpustakaan standard C , seperti memcpy, enggan bekerja dengan penunjuk null walaupun ketika menyalin sifar bait, menjadikan perbezaan antara null dan penunjuk sah penting secara praktikal.
Pendekatan paling selamat, menurut konsensus komuniti, adalah untuk mengelakkan malloc(0) sepenuhnya. Pembangun boleh meminta malloc(1) apabila mereka memerlukan alamat unik, atau membungkus malloc dalam fungsi tersuai yang menyediakan tingkah laku konsisten merentas semua sistem. Walaupun ini menambah kod tambahan, ia menghapuskan sumber masalah mudah alih yang ketara.
Penyelesaian Biasa Pembangun:
- Gunakan
malloc(1)
sebagai gantimalloc(0)
apabila alamat unik diperlukan - Balut malloc dalam fungsi tersuai untuk kelakuan yang konsisten
- Tambahkan saiz+1 kepada permintaan peruntukan untuk mengelakkan kes tepi bait sifar
- Laksanakan penjejakan memori khusus aplikasi untuk peruntukan bersaiz sifar
Kesimpulan
Perdebatan malloc(0) menggambarkan bagaimana keputusan teknikal yang kelihatan kecil boleh mempunyai akibat yang berkekalan. Apa yang bermula sebagai percubaan untuk menampung pelaksanaan sedia ada yang berbeza telah mencipta sumber kekeliruan dan pepijat yang kekal. Bagi pembangun moden, pengajarannya jelas: apabila piawaian membenarkan pelbagai tingkah laku, jalan paling selamat adalah mengelakkan bergantung kepada mana-mana yang khusus.
Nota teknikal: malloc adalah fungsi pengagihan memori dalam pengaturcaraan C yang menyimpan ruang untuk program menyimpan data. POSIX adalah satu set piawaian yang mentakrifkan bagaimana sistem pengendalian sepatutnya berkelakuan.