Como converter vetor em array

352

Como faço para converter um std::vector<double>para um double array[]?

ganuke
fonte
9
Meio que implora a pergunta de por quê? Você pode acessar um vetor como uma matriz. O que uma matriz faz que um vetor não faz?
Michael Dorgan 27/05
96
@ Michael O caso de uso típico que eu tenho é usar um vetor em meu próprio código e a necessidade de chamar uma função de terceiro que recebe um array
Michael Mrozek
7
A terminologia usada é confusa. Um ponteiro não é uma matriz. Queremos um ponteiro para o primeiro elemento de uma matriz ou uma matriz?
GManNickG 27/05
7
absolutamente uma pergunta real - bastante simples, também de fácil interpretação. reabra.
Dbliss 07/12
10
"Meio que implora a pergunta de por quê?" - Primeiro, mau uso dessa frase. Segundo, está sangrando o porquê óbvio.
Jim Balter

Respostas:

533

Existe um truque bastante simples para fazer isso, já que a especificação agora garante que os vetores armazenem seus elementos de forma contígua:

std::vector<double> v;
double* a = &v[0];
Michael Mrozek
fonte
29
@ganuke Você não está copiando, está fazendo um ponteiro que aponta para a matriz real que o vetor está usando internamente. Se você deseja copiar a resposta de GMan explica como
Michael Mrozek
4
@ganuke: O que é "a matriz"? Você precisa fornecer mais informações. Qual é o quadro geral?
GManNickG 27/05
6
@ganuke Você não precisa, apenas precisa de um double*que aponte para os mesmos dados. Esta resposta funciona exatamente nesse caso
Michael Mrozek
6
@guneykayim O vector é o dono da memória, você não deve liberá-lo
Michael Mrozek
23
std::vector<double> v; double* a = v.data();
SinoTrinity
148

Pelo que? Você precisa esclarecer: Você precisa de um ponteiro para o primeiro elemento de uma matriz ou uma matriz?

Se você está chamando uma função de API que espera a anterior, pode fazê-lo do_something(&v[0], v.size()), onde vé um vetor de doubles. Os elementos de um vetor são contíguos.

Caso contrário, você apenas precisará copiar cada elemento:

double arr[100];
std::copy(v.begin(), v.end(), arr);

Certifique-se de que não seja apenas arrgrande o suficiente, mas que arrseja preenchido ou que você tenha valores não inicializados.

GManNickG
fonte
15
Nota: use v.size () para obter o número de elementos para a nova matriz: double arr [v.size ()];
Rbaleksandar
7
@rbaleksandar: matrizes não podem ter um tamanho de expressão não constante.
GManNickG
@GManNickG: Funciona, mas acho que há algum mal-entendido aqui. Imagine o seguinte: você tem uma classe com vários ponteiros de vários tipos que precisam apontar para matrizes, que não são conhecidas no momento em que você define sua classe e que são criadas posteriormente liberando vários vetores e usando seu parâmetro de tamanho para determinar quanto espaço deve ser usado. Outro exemplo: uma função simples void arrayTest (unsigned int arrSize), que cria uma matriz (short arr [arrSize];) nela usando seu parâmetro de função para o tamanho.
Rbaleksandar
11
@rbaleksandar Sem mal-entendidos; no C ++ 11 e anteriores, os tamanhos de matriz devem ser expressões constantes integrais. Seu exemplo de função é um uso comum para VLAs em C, mas suportado apenas pela extensão (não padrão) em C ++. Pode ser no C ++ 14: stackoverflow.com/a/17318040/87234 . Mas, a partir de agora, simplesmente não é uma opção padrão.
GManNickG
11
@GManNickG Acho que o @Jet está dizendo que, se você deseja converter um vetor em uma matriz, e pretende dimensionar a matriz usando a size()função do std:vectorque precisará usar newou mallocfazer isso. Como já foi indicado (por você) que double arr[v.size()]não é válido. Usar vetor no lugar de novo é uma boa idéia, mas o ponto principal da questão é como você pode converter um vetor em uma matriz.
RyanP
17
vector<double> thevector;
//...
double *thearray = &thevector[0];

É garantido que ele funcione de acordo com o padrão, no entanto, existem algumas ressalvas: em particular, tome cuidado para usar apenas thearrayenquanto thevectorestiver no escopo.

user168715
fonte
4
... e verifique se o vetor não é empty(), caso contrário, isso invocaria o temido UB.
sbi 27/05
13

Os vetores são efetivamente matrizes sob a pele. Se você tem uma função:

void f( double a[]);

você pode chamar assim:

vector <double> v;
v.push_back( 1.23 )
f( &v[0] );

Você nunca precisa converter um vetor em uma instância de matriz real.


fonte
11
Eu acho que você quis f( &v[0] );para sua última linha
Michael Mrozek
10

Quanto ao std::vector<int> vecvec para obter int*, você pode usar dois métodos:

  1. int * arr = & vec [0];

  2. int * arr = vec.data ();

Se você deseja converter qualquer tipo de Tvetor para T* array, basta substituir o acima intpor T.

Eu vou lhe mostrar por que as duas obras acima, para um bom entendimento?

std::vector é uma matriz dinâmica essencialmente.

Membro de dados principal como abaixo:

template <class T, class Alloc = allocator<T>>
class vector{
    public:
        typedef T          value_type;
        typedef T*         iterator;
        typedef T*         pointer;
        //.......
    private:
        pointer start_;
        pointer finish_;
        pointer end_of_storage_;

    public:
        vector():start_(0), finish_(0), end_of_storage_(0){}
    //......
}

O range (start_, end_of_storage_)é toda a memória conjunto o vetor alocar;

A range(start_, finish_)é toda a memória da matriz que o vetor usou;

A range(finish_, end_of_storage_)é a memória da matriz de backup.

Por exemplo, quanto a um vetor vec. que tem {9, 9, 1, 2, 3, 4} como ponteiro, pode gostar do abaixo.

insira a descrição da imagem aqui

Então &vec[0]= start_ (endereço.) (Start_ é equivalente a int * array head)

c++11 Na data()função de membro de apenas retornar start_

pointer data()
{ 
     return start_; //(equivalent to `value_type*`, array head)
}
Jayhello
fonte
2

Podemos fazer isso usando o método data (). O C ++ 11 fornece esse método.

Fragmento de código

#include<bits/stdc++.h>
using namespace std;


int main()
{
  ios::sync_with_stdio(false);

  vector<int>v = {7, 8, 9, 10, 11};
  int *arr = v.data();

  for(int i=0; i<v.size(); i++)
  {
    cout<<arr[i]<<" ";
  }

  return 0;
}
rashedcs
fonte
2
std::vector<double> vec;
double* arr = vec.data();
Toby
fonte
1

Se você tem uma função, então você provavelmente terá o seguinte: foo(&array[0], array.size());. Se você conseguiu entrar em uma situação em que precisa de uma matriz, precisa refatorar, vetores são basicamente matrizes estendidas, sempre deve usá-las.


fonte
-1

Você pode fazer algo parecido com isto

vector <int> id;
vector <double> v;

if(id.size() > 0)
{
    for(int i = 0; i < id.size(); i++)
    {
        for(int j = 0; j < id.size(); j++)
        {
            double x = v[i][j];
            cout << x << endl;
        }
    }
}
Sakthi Vignesh
fonte
v [i] [j]; para matriz 2D
Sakthi Vignesh 30/10