Saya baru mulai masuk ke C ++ dan saya ingin mengambil beberapa kebiasaan baik. Jika saya baru saja mengalokasikan array tipe int
dengannew
operator, bagaimana saya bisa menginisialisasinya menjadi 0 tanpa melalui semuanya sendiri? Haruskah saya gunakan memset
? Apakah ada cara "C ++" untuk melakukannya?
c++
initialization
memory-management
new-operator
dreamlax
sumber
sumber
&vector[0]
.Jawaban:
Ini adalah fitur yang sangat sedikit diketahui dari C ++ (sebagaimana dibuktikan oleh fakta bahwa belum ada yang memberikan ini sebagai jawaban), tetapi sebenarnya memiliki sintaks khusus untuk menginisialisasi nilai array:
Perhatikan bahwa Anda harus menggunakan tanda kurung kosong - Anda tidak dapat, misalnya, menggunakan
(0)
atau apa pun lainnya (itulah sebabnya ini hanya berguna untuk inisialisasi nilai).Ini secara eksplisit diizinkan oleh ISO C ++ 03 5.3.4 [expr.new] / 15, yang mengatakan:
dan tidak membatasi jenis yang diizinkan ini, sedangkan
(expression-list)
formulir secara eksplisit dibatasi oleh aturan lebih lanjut di bagian yang sama sehingga tidak mengizinkan jenis array.sumber
new int[10] {}
. Anda juga dapat memberikan nilai untuk menginisialisasi dengan:new int[10] {1,2,3}
Dengan asumsi bahwa Anda benar-benar menginginkan array dan bukan std :: vector, "C ++ way" adalah ini
Tetapi perlu diketahui bahwa di bawah tenda ini sebenarnya masih hanya sebuah loop yang menetapkan setiap elemen ke 0 (benar-benar tidak ada cara lain untuk melakukannya, kecuali arsitektur khusus dengan dukungan tingkat perangkat keras).
sumber
Ada sejumlah metode untuk mengalokasikan array tipe intrinsik dan semua metode ini benar, meskipun yang mana untuk dipilih, tergantung ...
Inisialisasi manual semua elemen dalam lingkaran
Menggunakan
std::memset
fungsi dari<cstring>
Menggunakan
std::fill_n
algoritma dari<algorithm>
Menggunakan
std::vector
wadahJika C ++ 0x tersedia, gunakan fitur daftar penginisialisasi
sumber
int array[SIZE] ={1,2,3,4,5,6,7};
notasi, saya bisa menggunakanvoid rotateArray(int (& input)[SIZE], unsigned int k);
deklarasi fungsi saya, apa yang akan terjadi ketika menggunakan konvensi pertama? ada saran?std::memset
salah - Anda lulus 10, sepertinya mengharapkan jumlah byte - lihat en.cppreference.com/w/cpp/string/byte/memset . (Saya pikir ini dengan baik menunjukkan mengapa kita harus menghindari konstruksi tingkat rendah seperti itu bila mungkin.)Jika memori yang Anda alokasikan adalah kelas dengan konstruktor yang melakukan sesuatu yang bermanfaat, operator yang baru akan memanggil konstruktor itu dan membiarkan objek Anda diinisialisasi.
Tetapi jika Anda mengalokasikan POD atau sesuatu yang tidak memiliki konstruktor yang menginisialisasi keadaan objek, maka Anda tidak dapat mengalokasikan memori dan menginisialisasi memori itu dengan operator yang baru dalam satu operasi. Namun, Anda memiliki beberapa opsi:
1) Gunakan variabel tumpukan sebagai gantinya. Anda dapat mengalokasikan dan menginisialisasi default dalam satu langkah, seperti ini:
2) gunakan
memset()
. Perhatikan bahwa jika objek yang Anda alokasikan bukan POD alokasikan , memsetting itu adalah ide yang buruk. Salah satu contoh spesifik adalah jika Anda memset kelas yang memiliki fungsi virtual, Anda akan menerbangkan vtable dan meninggalkan objek Anda dalam keadaan tidak dapat digunakan.3) Banyak sistem operasi memiliki panggilan yang melakukan apa yang Anda inginkan - mengalokasikan pada tumpukan dan menginisialisasi data untuk sesuatu. Contoh Windows akan menjadi
VirtualAlloc()
4) Ini biasanya merupakan pilihan terbaik. Hindari mengatur memori sendiri. Anda dapat menggunakan wadah STL untuk melakukan apa saja yang Anda lakukan dengan memori mentah, termasuk mengalokasikan dan menginisialisasi semua dalam satu gerakan:
sumber
Ya ada:
Gunakan vektor alih-alih array yang dialokasikan secara dinamis. Manfaatnya termasuk tidak perlu repot menghapus array secara eksplisit (itu dihapus ketika vektor keluar dari ruang lingkup) dan juga bahwa memori secara otomatis dihapus bahkan jika ada pengecualian yang dilemparkan.
Sunting: Untuk menghindari downvotes drive-by lebih lanjut dari orang-orang yang tidak repot-repot membaca komentar di bawah, saya harus membuatnya lebih jelas bahwa jawaban ini tidak mengatakan bahwa vektor selalu merupakan jawaban yang tepat. Tapi itu jelas merupakan cara yang lebih C ++ daripada "secara manual" memastikan untuk menghapus array.
Sekarang dengan C ++ 11, ada juga std :: array yang memodelkan array ukuran konstan (vs vektor yang dapat tumbuh). Ada juga std :: unique_ptr yang mengelola array yang dialokasikan secara dinamis (yang dapat dikombinasikan dengan inisialisasi seperti dijawab dalam jawaban lain untuk pertanyaan ini). Semua itu adalah cara yang lebih C ++ daripada secara manual menangani pointer ke array, IMHO.
sumber
std::vector
alih-alih array yang dialokasikan secara dinamis? Apa manfaat menggunakan array di atas vektor, dan sebaliknya?std::vector
.vector
mana-mana terlepas dari konteksnya disebut "Menulis kode Java dalam C ++".std::fill
adalah satu arah. Mengambil dua iterator dan nilai untuk mengisi wilayah. Itu, atau untuk loop, akan (saya kira) menjadi lebih banyak cara C ++.Untuk mengatur larik tipe integer primitif ke 0 secara khusus,
memset
tidak masalah, meskipun dapat menaikkan alis. Pertimbangkan jugacalloc
, meskipun agak tidak nyaman untuk digunakan dari C ++ karena para pemain.Bagi saya, saya cukup sering menggunakan loop.
(Saya tidak suka menebak-nebak niat orang, tetapi memang benar bahwa
std::vector
, semua hal dianggap sama, lebih baik daripada menggunakannew[]
.)sumber
Anda selalu dapat menggunakan memset:
sumber
memset
, tetapi saya tidak yakin apakah ini adalah cara C ++ untuk mendekati masalah.10 * sizeof( *myArray )
lebih terdokumentasi dan tahan terhadap perubahan10 * sizeof( int )
.Biasanya untuk daftar item yang dinamis, Anda menggunakan a
std::vector
.Secara umum saya menggunakan memset atau loop untuk alokasi dinamis memori mentah, tergantung pada bagaimana variabel saya mengantisipasi area kode di masa depan.
sumber