Làm thế nào để có được std :: vector con trỏ đến dữ liệu thô?


160

Tôi đang cố gắng sử dụng std::vectornhư một charmảng.

Hàm của tôi mất trong một con trỏ trống:

void process_data(const void *data);

Trước đây tôi chỉ đơn giản là sử dụng mã này:

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

Mà làm việc như mong đợi.

Nhưng bây giờ tôi cần sự năng động của std::vector, vì vậy tôi đã thử mã này thay thế:

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

Câu hỏi là, làm thế nào để tôi chuyển vector char cho hàm của mình để tôi có thể truy cập dữ liệu thô của vector (bất kể nó ở định dạng nào - float, v.v.)?

Tôi đã thử điều này:

process_data(&something);

Và điều này:

process_data(&something.begin());

Nhưng nó đã trả về một con trỏ tới dữ liệu vô nghĩa và sau đó đã đưa ra cảnh báo : warning C4238: nonstandard extension used : class rvalue used as lvalue.

Câu trả lời:


238

&somethingcung cấp cho bạn địa chỉ của std::vectorđối tượng, không phải địa chỉ của dữ liệu mà nó lưu giữ. &something.begin()cung cấp cho bạn địa chỉ của trình lặp được trả về bởi begin()(như trình biên dịch cảnh báo, điều này không được phép về mặt kỹ thuật vì something.begin()là biểu thức giá trị, vì vậy không thể lấy địa chỉ của nó).

Giả sử container có ít nhất một phần tử trong đó, bạn cần lấy địa chỉ của phần tử ban đầu của container, bạn có thể lấy thông qua

  • &something[0]hoặc &something.front()(địa chỉ của phần tử tại chỉ mục 0) hoặc

  • &*something.begin()(địa chỉ của phần tử được chỉ ra bởi iterator được trả về bởi begin()).

Trong C ++ 11, một hàm thành viên mới đã được thêm vào std::vector: data(). Hàm thành viên này trả về địa chỉ của phần tử ban đầu trong vùng chứa, giống như &something.front(). Ưu điểm của chức năng thành viên này là ổn khi gọi nó ngay cả khi container rỗng.


103
Cảnh giác quan trọng trong vector<bool>đó là ngoại lệ cho câu trả lời này (và không có bộ nhớ lưu trữ liền kề của bools).
Motti

18
Về mặt sáng sủa, không có gì đáng để cảnh giác: cả ba phương thức này sẽ không biên dịch được std::vector<bool>std::vector<bool>yêu cầu sử dụng một đối tượng proxy và proxy đó không thể được chuyển đổi thành a bool*. Như cách giải quyết cho vấn đề này, nếu bạn cần một chuỗi bool, tốt nhất chỉ nên sử dụng một std::vector<char>. @Motti
James McNellis

Đúng, hãy cẩn thận là nói chung chứ không phải đạo diễn là câu trả lời của bạn, vì không có bộ nhớ lưu trữ tiếp giáp không có cách nào để có được vào nó.
Motti

7
trở nên toàn diện nhưng chủ yếu là cho .data()- Tôi sẽ chỉ giả vờ rằng tôi không thấy điều đó xấu xí &*iterator: P
underscore_d

2
Con trỏ trở về từ bao lâu data()? Nếu vectơ không bao giờ thay đổi kích thước lớn hơn hoặc nhỏ hơn (thông qua push_back()hoặc các hàm khác, bao gồm reserve), liệu có đảm bảo rằng con trỏ sẽ sống miễn là vectơ sống, chỉ đến đúng vị trí?
johnbakers

81

something.data() sẽ trả về một con trỏ tới không gian dữ liệu của vectơ.


error C2039: 'data' : is not a member of 'std::vector<_Ty>'
Tân binh

2
@Rookie: có vẻ như bạn đang sử dụng trình biên dịch bị hỏng - 23.3.6.3 trong thông số C ++ xác định vector :: data. Hãy thử gửi một lỗi với nhà cung cấp của bạn hoặc nhận được một trình biên dịch tốt hơn.
Chris Dodd

1
@Chris Dodd Tôi cũng bị lỗi tương tự. Tôi đang sử dụng Visual Studio 2008
bodacydo

34
@ChrisDodd: vector::data()mới đối với C ++ 11
HighCommander4

Tôi sử dụng Visual Studio 2012 và họ phải thêm vector :: data () vì tôi sử dụng nó một bó.
Robert Snyder

12

Thay vào đó, lấy một con trỏ tới phần tử đầu tiên:

process_data (&something [0]);

Tôi nghĩ rằng nó sẽ trả về địa chỉ bộ nhớ của mục đầu tiên ngay cả khi không có dấu ngoặc đơn?
Tim

Đó là cho mảng, không phải cho vectơ.
Steven Don

Vâng chỉ nhận ra rằng, xin lỗi.
Tim
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.