Como obter o ponteiro std :: vector para os dados brutos?

160

Estou tentando usar std::vectorcomo uma charmatriz.

Minha função recebe um ponteiro nulo:

void process_data(const void *data);

Antes eu simplesmente usava esse código:

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

O que funcionou como esperado.

Mas agora eu preciso da dinâmica de std::vector, então tentei este código:

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

A questão é: como passo o vetor char para a minha função para que eu possa acessar os dados brutos do vetor (independentemente do formato) - flutua etc.)?

Eu tentei isso:

process_data(&something);

E isto:

process_data(&something.begin());

Mas ele retornou um ponteiro para dados jargão, eo último deu o aviso: warning C4238: nonstandard extension used : class rvalue used as lvalue.

Novato
fonte

Respostas:

238

&somethingfornece o endereço do std::vectorobjeto, não o endereço dos dados que ele contém. &something.begin()fornece o endereço do iterador retornado por begin()(como o compilador avisa, isso não é tecnicamente permitido porque something.begin()é uma expressão rvalue, portanto, seu endereço não pode ser utilizado).

Supondo que o contêiner tenha pelo menos um elemento, você precisa obter o endereço do elemento inicial do contêiner, que pode ser obtido por meio de

  • &something[0]ou &something.front()(o endereço do elemento no índice 0), ou

  • &*something.begin()(o endereço do elemento apontado pelo iterador retornado por begin()).

Em C ++ 11, uma nova função membro foi adicionado a std::vector: data(). Esta função de membro retorna o endereço do elemento inicial no contêiner, assim como &something.front(). A vantagem dessa função de membro é que não há problema em chamá-la, mesmo que o contêiner esteja vazio.

James McNellis
fonte
103
Importante Cuidado com o vector<bool>que é a exceção a esta resposta (e não possui um armazenamento contíguo de bools).
Motti 26/06
18
Pelo lado positivo, não há muito o que se preocupar: todos esses três métodos não serão compilados std::vector<bool>porque std::vector<bool>requer o uso de um objeto proxy e esse proxy não pode ser implicitamente convertido em a bool*. Como solução alternativa para isso, se você precisar de uma sequência de bool, é melhor usar apenas a std::vector<char>. @Motti
James McNellis 26/06
É verdade que o cuidado foi geral e não foi direcionado como sua resposta, já que não há armazenamento de memória contíguo, não há como obtê-lo.
Motti 27/06
7
-se por ser abrangente, mas principalmente para .data()- I'lll apenas fingir que não vê que feio &*iterator: P
underscore_d
2
por quanto tempo o ponteiro retornará do data()live? Se o vetor nunca for redimensionado, seja maior ou menor (via push_back()ou outras funções, inclusive reserve), é garantido que o ponteiro permanecerá enquanto o vetor permanecer, apontando para o local correto?
21416 Johnbakers
81

something.data() retornará um ponteiro para o espaço de dados do vetor.

Chris Dodd
fonte
error C2039: 'data' : is not a member of 'std::vector<_Ty>'
Rookie
2
@Rookie: parece que você está usando um compilador quebrado - 23.3.6.3 na especificação C ++ define vector :: data. Tente registrar um bug com seu fornecedor ou obter um compilador melhor.
22611 Chris Dodd
1
@ Chris Dodd Eu tenho o mesmo erro. Estou usando o Visual Studio 2008.
bodacydo
34
@ChrisDodd: vector::data()é novo no C ++ 11
HighCommander4
Eu uso o Visual Studio 2012 e eles devem ter adicionado o vetor :: data () porque eu o uso muito.
Robert Snyder
12

Pegue um ponteiro para o primeiro elemento:

process_data (&something [0]);
Steven Don
fonte
Eu pensei que iria retornar o endereço de memória do primeiro item, mesmo sem os colchetes subscritos?
Tim
Isso é para matrizes, não para vetores.
Steven Don
Sim, acabei de perceber isso, desculpe.
Tim