Pertanyaan saya sederhana: apakah elemen std :: vector dijamin bersebelahan? Dalam urutan kata, dapatkah saya menggunakan penunjuk ke elemen pertama dari std :: vector sebagai C-array?
Jika ingatan saya bermanfaat bagi saya, standar C ++ tidak membuat jaminan seperti itu. Namun, persyaratan std :: vector sedemikian rupa sehingga hampir tidak mungkin untuk memenuhinya jika elemen tidak bersebelahan.
Adakah yang bisa menjelaskan ini?
Contoh:
std::vector<int> values;
// ... fill up values
if( !values.empty() )
{
int *array = &values[0];
for( int i = 0; i < values.size(); ++i )
{
int v = array[i];
// do something with 'v'
}
}
values
di dalamif
blok itu. Saya tidak tahu jawaban atas pertanyaan Anda, jadi saya hanya meninggalkan komentar. :)values
, khususnya yang mengubah ukurannya (mis.,push_back()
), Dapat meminta realokasi vektor yang mendasari yang membatalkan penunjuk yang disalinarray
. Ini prinsip yang sama di belakang menggunakan vektor :: iterator alih-alih penunjuk ke vektor. :)Jawaban:
Ini terlewatkan dari standar C ++ 98 tetapi kemudian ditambahkan sebagai bagian dari TR. Standar C ++ 0x yang akan datang tentu saja akan memuat ini sebagai persyaratan.
Dari n2798 (draf C ++ 0x):
sumber
std::vector
ini yang berdekatan. Misalnya: dalamstd::vector<std::vector<int>> v
elemenv[0]
,,v[1]
... disimpan kemudian dalam memori, tetapi elemenv[0].back()
danv[1].front()
tidak dijamin akan.Seperti jawaban lain yang telah ditunjukkan, konten vektor dijamin kontinu (kecuali keanehan bool).
Komentar yang ingin saya tambahkan, adalah jika Anda melakukan penyisipan atau penghapusan pada vektor, yang dapat menyebabkan vektor mengalokasikan kembali memorinya, maka Anda akan menyebabkan semua penunjuk dan iterator yang disimpan menjadi tidak valid.
sumber
Standar sebenarnya menjamin bahwa a
vector
kontinu dalam memori dan&a[0]
dapat diteruskan keC
fungsi yang mengharapkan sebuah array.Pengecualian untuk aturan ini adalah
vector<bool>
yang hanya menggunakan satu bit perbool
dengan demikian meskipun ia memiliki memori berkelanjutan, ia tidak dapat digunakan sebagaibool*
(ini secara luas dianggap sebagai pengoptimalan palsu dan kesalahan).BTW, kenapa tidak Anda menggunakan iterator? Untuk itulah mereka.
sumber
Seperti yang telah dikatakan orang lain, secara
vector
internal menggunakan array objek yang berdekatan. Pointer ke dalam array itu harus diperlakukan sebagai tidak valid setiap kali ada fungsi anggota non-const yang disebut IIRC.Namun, ada pengecualian !!
vector<bool>
memiliki implementasi khusus yang dirancang untuk menghemat ruang, sehingga setiap bool hanya menggunakan satu bit. Array yang mendasari bukanlah array bool dan aritmatika array yang berdekatanvector<bool>
tidak berfungsi seperti yang diharapkanvector<T>
.(Saya kira itu juga mungkin bahwa ini mungkin benar untuk setiap spesialisasi vektor, karena kita selalu dapat menerapkan yang baru. Namun,
std::vector<bool>
adalah satu-satunya, err, spesialisasi standar yang aritmatika penunjuk sederhana tidak akan berfungsi.)sumber
std::vector
, dan semua vektor lain diperlukan untuk menggunakan penyimpanan yang berdekatan. Oleh karena itu,std::vector<bool>
(untungnya) adalah satu-satunya vektor standar yang aneh. (Saya sangat berpendapat bahwa spesialisasi ini harus ditinggalkan dan diganti dengan mis. Astd::dynamic_bitset
dengan banyak fungsi yang sama. Ini bukan struktur data yang buruk, ini hanya bukan vektor.)Saya menemukan utas ini karena saya memiliki kasus penggunaan di mana vektor yang menggunakan memori bersebelahan adalah keuntungan.
Saya belajar bagaimana menggunakan objek buffer vertex di OpenGL. Saya membuat kelas pembungkus untuk memuat logika buffer, jadi yang perlu saya lakukan adalah melewatkan array floats dan beberapa nilai konfigurasi untuk membuat buffer. Saya ingin dapat menghasilkan buffer dari suatu fungsi berdasarkan input pengguna, sehingga panjangnya tidak diketahui pada waktu kompilasi. Melakukan sesuatu seperti ini akan menjadi solusi termudah:
Sekarang saya bisa melewatkan float vektor sebagai array ke fungsi terkait buffer OpenGL. Ini juga menghilangkan kebutuhan sizeof untuk menentukan panjang array.
Ini jauh lebih baik daripada mengalokasikan array besar untuk menyimpan float dan berharap saya membuatnya cukup besar, atau membuat array dinamis saya sendiri dengan penyimpanan yang berdekatan.
sumber
v
daripadav
dirinya sendiri? karena melewatkanv
sendiri akan menyebabkan salinan dibuat di dalam fungsi, yang tidak akan ada lagi setelah fungsi berakhir. Jadi Anda mendorong sesuatu ke vektor hanya untuk menghapus vektor saat fungsi berakhir.cplusplus.com:
sumber
Ya, elemen dari std :: vector dijamin bersebelahan.
sumber