Saya memiliki larik nilai yang diteruskan ke fungsi saya dari bagian lain dari program yang perlu saya simpan untuk diproses nanti. Karena saya tidak tahu berapa kali fungsi saya akan dipanggil sebelum waktunya untuk memproses data, saya memerlukan struktur penyimpanan dinamis, jadi saya memilih file std::vector
. Saya tidak ingin melakukan loop standar ke push_back
semua nilai secara individual, alangkah baiknya jika saya dapat menyalin semuanya menggunakan sesuatu yang mirip dengan memcpy
.
vec.assign(a, a+n)
, yang akan lebih kompak dari copy & resize.Ada banyak jawaban di sini dan hampir semuanya akan menyelesaikan pekerjaan.
Namun ada beberapa nasihat yang menyesatkan!
Berikut opsinya:
Untuk mempersingkat cerita, Metode 4, menggunakan vector :: insert, adalah yang terbaik untuk skenario bsruth.
Berikut beberapa detail berdarah:
Metode 1 mungkin yang paling mudah dipahami. Cukup salin setiap elemen dari array dan dorong ke belakang vektor. Sayangnya, ini lambat. Karena ada loop (tersirat dengan fungsi copy), setiap elemen harus diperlakukan secara individual; tidak ada peningkatan kinerja yang dapat dibuat berdasarkan fakta bahwa kita mengetahui bahwa array dan vektor adalah blok yang berdekatan.
Metode 2 adalah peningkatan kinerja yang disarankan untuk Metode 1; cukup pra-pesan ukuran array sebelum menambahkannya. Untuk array besar, ini mungkin membantu. Namun saran terbaik di sini adalah jangan pernah menggunakan reserve kecuali profil menunjukkan Anda mungkin bisa mendapatkan peningkatan (atau Anda perlu memastikan iterator Anda tidak akan dibatalkan). Bjarne setuju . Kebetulan, saya menemukan bahwa metode ini melakukan paling lambat sebagian besar waktu meskipun aku berjuang untuk secara komprehensif menjelaskan mengapa hal itu teratur secara signifikan lebih lambat dari metode 1 ...
Metode 3 adalah solusi jadul - berikan beberapa C pada masalah ini! Bekerja dengan baik dan cepat untuk jenis POD. Dalam hal ini, pengubahan ukuran harus dipanggil karena memcpy bekerja di luar batas vektor dan tidak ada cara untuk memberi tahu vektor bahwa ukurannya telah berubah. Selain sebagai solusi yang jelek (penyalinan byte!), Ingatlah bahwa ini hanya dapat digunakan untuk jenis POD . Saya tidak akan pernah menggunakan solusi ini.
Metode 4 adalah cara terbaik untuk melakukannya. Artinya jelas, (biasanya) tercepat dan berfungsi untuk objek apa pun. Tidak ada kerugian menggunakan metode ini untuk aplikasi ini.
Metode 5 adalah tweak pada Metode 4 - salin array ke dalam vektor dan kemudian tambahkan. Pilihan bagus - umumnya cepat dan jelas.
Akhirnya, Anda sadar bahwa Anda dapat menggunakan vektor sebagai pengganti array, bukan? Bahkan ketika suatu fungsi mengharapkan array gaya-c Anda bisa menggunakan vektor:
Harapan yang membantu seseorang di luar sana!
sumber
&expr
tidak mengevaluasiexpr
, itu hanya menghitung alamatnya. Dan pointer satu masa lalu elemen terakhir benar-benar berlaku, juga.dataVec.insert(dataVec.end(), dataArray, dataArray + dataArraySize);
- tampak jauh lebih jelas bagi saya. Tidak dapat memperoleh apa pun dari metode 5, hanya terlihat sangat tidak efisien - kecuali kompiler dapat mengoptimalkan vektor lagi.Jika yang Anda lakukan hanyalah mengganti data yang ada, maka Anda bisa melakukan ini
sumber
std :: copy adalah apa yang Anda cari.
sumber
Karena saya hanya dapat mengedit jawaban saya sendiri, saya akan membuat jawaban gabungan dari jawaban lain atas pertanyaan saya. Terima kasih untuk semua yang menjawab.
Menggunakan std :: copy , ini masih berulang di latar belakang, tetapi Anda tidak perlu mengetikkan kodenya.
Menggunakan memcpy biasa . Ini mungkin paling baik digunakan untuk tipe data dasar (yaitu int) tetapi tidak untuk array struct atau class yang lebih kompleks.
sumber
hindari memcpy, kataku. Tidak ada alasan untuk mengacaukan operasi penunjuk kecuali Anda benar-benar harus melakukannya. Selain itu, ini hanya akan berfungsi untuk jenis POD (seperti int) tetapi akan gagal jika Anda berurusan dengan jenis yang memerlukan konstruksi.
sumber
sumber
myints
?Namun jawaban lain, karena orang tersebut berkata "Saya tidak tahu berapa kali fungsi saya akan dipanggil", Anda dapat menggunakan metode penyisipan vektor seperti itu untuk menambahkan array nilai ke akhir vektor:
Saya suka cara ini karena implementasi vektor harus dapat mengoptimalkan cara terbaik untuk memasukkan nilai berdasarkan tipe iterator dan tipe itu sendiri. Anda agak membalas penerapan stl.
Jika Anda perlu menjamin kecepatan tercepat dan Anda tahu tipe Anda adalah tipe POD maka saya akan merekomendasikan metode pengubahan ukuran dalam jawaban Thomas:
sumber
Selain metode yang disajikan di atas, Anda perlu memastikan bahwa Anda menggunakan std :: Vector.reserve (), std :: Vector.resize (), atau buat vektor ke ukuran, untuk memastikan vektor Anda memiliki cukup elemen itu untuk menyimpan data Anda. jika tidak, Anda akan merusak memori. Ini berlaku untuk std :: copy () atau memcpy ().
Ini adalah alasan untuk menggunakan vector.push_back (), Anda tidak bisa menulis melewati akhir vektor.
sumber
Dengan asumsi Anda tahu seberapa besar item dalam vektor adalah:
http://www.cppreference.com/wiki/stl/vector/start
sumber