원시 데이터에 std :: vector 포인터를 얻는 방법?


160

내가 사용하려고 해요 std::vectorA와 char배열입니다.

내 함수는 void 포인터를 사용합니다.

void process_data(const void *data);

이 코드를 사용하기 전에 :

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

예상대로 작동했습니다.

그러나 이제의 동 적성이 필요 std::vector하므로 대신이 코드를 사용해보십시오.

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

문제는 char 벡터를 내 함수에 어떻게 전달하여 벡터 원시 데이터에 액세스 할 수 있습니까 (어떤 형식이든-부동 소수점 등)?

나는 이것을 시도했다 :

process_data(&something);

이:

process_data(&something.begin());

그러나 그것은 횡설수설 한 데이터에 대한 포인터를 반환했고 후자는 경고를 주었다 warning C4238: nonstandard extension used : class rvalue used as lvalue.

답변:


238

&somethingstd::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>하는이 답변에 예외 (와의 연속적인 메모리 저장하지 않습니다 bool들).
Motti

18
밝은면에는주의해야 할 것이 많지 않습니다 . 프록시 객체를 사용해야하고 프록시가 암시 적으로로 변환 될 수 std::vector<bool>없기 때문에이 세 가지 메소드 모두 컴파일에 실패 std::vector<bool>합니다 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
@ 신인 : 깨진 컴파일러를 사용하는 것처럼 보입니다 .C ++ 사양에서 23.3.6.3은 vector :: data를 정의합니다. 공급 업체에 버그를 제기하거나 더 나은 컴파일러를 사용해보십시오.
Chris Dodd

1
@Chris Dodd 같은 오류가 있습니다. Visual Studio 2008을 사용하고 있습니다.
bodacydo

34
@ChrisDodd : vector::data()C ++ 11의 새로운 기능
HighCommander4 2016 년

Visual Studio 2012를 사용하고 vector :: data ()를 묶어야하므로 vector :: data ()를 추가해야합니다.
Robert Snyder

12

첫 번째 요소에 대한 포인터를 대신 사용하십시오.

process_data (&something [0]);

첨자 괄호가 없어도 첫 번째 항목의 메모리 주소를 반환한다고 생각 했습니까?
Tim

벡터가 아닌 배열입니다.
Steven Don

네, 방금 깨달았습니다. 죄송합니다.
Tim
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.