วิธีรับ std :: vector pointer ไปยังข้อมูลดิบ?


160

ฉันพยายามที่จะใช้std::vectorเป็นcharอาร์เรย์

ฟังก์ชั่นของฉันใช้เป็นตัวชี้โมฆะ:

void process_data(const void *data);

ก่อนที่ฉันจะใช้รหัสนี้:

char something[] = "my data here";
process_data(something);

ซึ่งทำงานได้ตามที่คาดหวัง

แต่ตอนนี้ฉันต้องการพลังของstd::vectorฉันจึงลองใช้รหัสนี้แทน:

vector<char> something;
*cut*
process_data(something);

คำถามคือฉันจะส่ง char vector ไปยังฟังก์ชันของฉันได้อย่างไรเพื่อให้ฉันสามารถเข้าถึงข้อมูล raw ของเวกเตอร์ได้ (ไม่ว่าจะเป็นรูปแบบใด - float ฯลฯ )

ฉันลองสิ่งนี้:

process_data(&something);

และนี่:

process_data(&something.begin());

warning C4238: nonstandard extension used : class rvalue used as lvalueแต่มันกลับชี้ไปยังข้อมูลที่ไม่มีความหมายและหลังให้คำเตือน:

คำตอบ:


238

&somethingให้ที่อยู่ของstd::vectorวัตถุไม่ใช่ที่อยู่ของข้อมูลที่เก็บไว้ &something.begin()ให้ที่อยู่ของตัววนซ้ำที่ส่งคืนโดยbegin()(ในขณะที่คอมไพเลอร์เตือนสิ่งนี้ไม่ได้รับอนุญาตทางเทคนิคเพราะsomething.begin()เป็นนิพจน์ rvalue ดังนั้นจึงไม่สามารถใช้ที่อยู่ของมันได้)

สมมติว่าคอนเทนเนอร์มีองค์ประกอบอย่างน้อยหนึ่งรายการคุณต้องได้รับที่อยู่ขององค์ประกอบเริ่มต้นของคอนเทนเนอร์ซึ่งคุณสามารถรับผ่าน

  • &something[0]หรือ&something.front()(ที่อยู่ขององค์ประกอบที่ดัชนี 0) หรือ

  • &*something.begin()(ที่อยู่ขององค์ประกอบที่ชี้โดยตัววนซ้ำที่ส่งคืนโดยbegin())

ใน C ++ 11 ฟังก์ชั่นสมาชิกใหม่ที่ถูกเพิ่มเข้ามาใน:std::vector ฟังก์ชันนี้สมาชิกส่งกลับที่อยู่ขององค์ประกอบเบื้องต้นในภาชนะที่เช่นเดียวกับdata() &something.front()ข้อดีของฟังก์ชั่นสมาชิกนี้คือมันไม่เป็นไรที่จะเรียกมันแม้ว่าคอนเทนเนอร์จะว่าง


103
สำคัญระวังvector<bool>ซึ่งเป็นข้อยกเว้นของคำตอบนี้ (และไม่มีหน่วยความจำที่ต่อเนื่องกันของbools)
Motti

18
ในด้านที่สว่างไสวมีสิ่งที่ต้องระวังไม่มาก: วิธีการทั้งสามนี้จะไม่สามารถคอมไพล์ได้std::vector<bool>เนื่องจากstd::vector<bool>ต้องใช้วัตถุพร็อกซีและพร็อกซีนั้นไม่สามารถแปลงเป็น a bool*ได้ ในฐานะที่เป็นวิธีแก้ปัญหานี้ถ้าคุณไม่จำเป็นต้องมีลำดับของจะดีที่สุดเพียงเพื่อการใช้งานbool std::vector<char>@Motti
James McNellis

จริงก็คือระวังโดยทั่วไปและไม่ได้เป็นคำตอบของคุณเนื่องจากไม่มีที่เก็บข้อมูลหน่วยความจำต่อเนื่องไม่มีทางที่จะไปถึงได้
Motti

7
ขึ้นสำหรับการเป็นที่ครอบคลุม แต่ส่วนใหญ่สำหรับ.data()- ฉันจะแกล้งทำเป็นว่าฉันไม่เห็นว่าน่าเกลียด&*iterator: P
underscore_d

2
ตัวชี้จะกลับมาจากการdata()แสดงสดนานเท่าใด หากเวกเตอร์ไม่มีการปรับขนาดใหญ่ขึ้นหรือเล็กลง (ผ่านpush_back()หรือฟังก์ชั่นอื่น ๆ รวมถึงreserve) มันรับประกันได้หรือไม่ว่าตัวชี้จะมีชีวิตอยู่ตราบใดที่เวกเตอร์มีชีวิตอยู่ชี้ไปยังตำแหน่งที่ถูกต้องหรือไม่?
johnbakers

81

something.data() จะกลับตัวชี้ไปยังพื้นที่ข้อมูลของเวกเตอร์


error C2039: 'data' : is not a member of 'std::vector<_Ty>'
Rookie

2
@Rookie: ดูเหมือนว่าคุณกำลังใช้คอมไพเลอร์ที่เสีย - 23.3.6.3 ในข้อมูลจำเพาะ C ++ กำหนด vector :: data ลองส่งบั๊กกับผู้จำหน่ายหรือรับคอมไพเลอร์ที่ดีขึ้น
Chris Dodd

1
@Chris Dodd ฉันมีข้อผิดพลาดเดียวกัน ฉันใช้ Visual Studio 2008
bodacydo

34
@ChrisDodd: vector::data()ยังใหม่กับ C ++ 11
HighCommander4

ฉันใช้ Visual Studio 2012 และพวกเขาจะต้องเพิ่มเวกเตอร์ :: data () เพราะฉันใช้มันเป็นพวง
Robert Snyder

12

นำตัวชี้ไปที่องค์ประกอบแรกแทน:

process_data (&something [0]);

ฉันคิดว่ามันจะส่งคืนที่อยู่หน่วยความจำของรายการแรกแม้ไม่มีวงเล็บย่อย
ทิม

สำหรับอาร์เรย์ไม่ใช่สำหรับเวกเตอร์
Steven Don

ใช่เพิ่งรู้ว่าขอโทษ
ทิม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.