Eu tenho uma matriz de valores que é passada para minha função de uma parte diferente do programa que preciso armazenar para processamento posterior. Como não sei quantas vezes minha função será chamada antes da hora de processar os dados, preciso de uma estrutura de armazenamento dinâmica, então escolhi a std::vector
. Eu não quero ter que fazer o loop padrão parapush_back
todos os valores individualmente, seria bom se eu pudesse apenas copiar tudo usando algo semelhante a memcpy
.
vec.assign(a, a+n)
, o que seria mais compacto do que copiar e redimensionamento.Houve muitas respostas aqui e quase todas elas farão o trabalho.
No entanto, existem alguns conselhos enganosos!
Aqui estão as opções:
Para encurtar a história, o Método 4, usando vector :: insert, é o melhor para o cenário de bsruth.
Aqui estão alguns detalhes sangrentos:
Método 1 é provavelmente o mais fácil de entender. Basta copiar cada elemento da matriz e colocá-lo na parte de trás do vetor. Infelizmente, é lento. Como há um loop (implícito na função de cópia), cada elemento deve ser tratado individualmente; nenhuma melhoria de desempenho pode ser feita com base no fato de que sabemos que a matriz e os vetores são blocos contíguos.
O Método 2 é uma sugestão de melhoria de desempenho para o Método 1; apenas pré-reserve o tamanho do array antes de adicioná-lo. Para matrizes grandes, isso pode ajudar. No entanto, o melhor conselho aqui é nunca usar reserva, a menos que a criação de perfil sugira que você possa obter uma melhoria (ou você precisa garantir que seus iteradores não sejam invalidados). Bjarne concorda . A propósito, descobri que esse método tinha desempenho mais lento na maioria das vezes, embora eu esteja lutando para explicar de forma abrangente por que era regularmente significativamente mais lento do que o método 1 ...
O método 3 é a solução da velha escola - jogue um pouco de C no problema! Funciona bem e rápido para tipos de POD. Nesse caso, resize deve ser chamado, pois memcpy funciona fora dos limites do vetor e não há como dizer a um vetor que seu tamanho mudou. Além de ser uma solução feia (cópia de bytes!), Lembre-se de que isso só pode ser usado para tipos POD . Eu nunca usaria essa solução.
O Método 4 é o melhor caminho a seguir. O significado é claro, é (geralmente) o mais rápido e funciona para qualquer objeto. Não há nenhuma desvantagem em usar este método para esta aplicação.
O Método 5 é um ajuste no Método 4 - copie a matriz em um vetor e, em seguida, anexe-a. Boa opção - geralmente rápido e claro.
Finalmente, você está ciente de que pode usar vetores no lugar de matrizes, certo? Mesmo quando uma função espera matrizes de estilo c, você pode usar vetores:
Espero que ajude alguém por aí!
fonte
&expr
não avaliaexpr
, só computa o endereço dele. E um ponteiro de um passado o último elemento é perfeitamente válido, também.dataVec.insert(dataVec.end(), dataArray, dataArray + dataArraySize);
- parece muito mais claro para mim. Também não é possível ganhar nada com o método 5, apenas parece bastante ineficiente - a menos que o compilador seja capaz de otimizar o vetor novamente.Se tudo o que você está fazendo é substituir os dados existentes, você pode fazer isso
fonte
std :: copy é o que você está procurando.
fonte
Como só posso editar minha própria resposta, farei uma resposta composta com as outras respostas à minha pergunta. Obrigado a todos vocês que responderam.
Usando std :: copy , isso ainda itera em segundo plano, mas você não precisa digitar o código.
Usando memcpy regular . Provavelmente, é melhor usado para tipos de dados básicos (ou seja, int), mas não para matrizes mais complexas de estruturas ou classes.
fonte
evite o memcpy, eu digo. Não há razão para mexer com as operações de ponteiro, a menos que seja realmente necessário. Além disso, só funcionará para tipos de POD (como int), mas falhará se você estiver lidando com tipos que requerem construção.
fonte
fonte
myints
?Ainda outra resposta, uma vez que a pessoa disse "Não sei quantas vezes minha função será chamada", você poderia usar o método de inserção de vetor para anexar matrizes de valores ao final do vetor:
Gosto dessa forma porque a implementação do vetor deve ser capaz de otimizar a melhor maneira de inserir os valores com base no tipo de iterador e no próprio tipo. Você está respondendo um pouco sobre a implementação de stl.
Se você precisa garantir a velocidade mais rápida e sabe que seu tipo é um tipo POD, eu recomendaria o método de redimensionamento na resposta de Thomas:
fonte
Além dos métodos apresentados acima, você precisa ter certeza de usar std :: Vector.reserve (), std :: Vector.resize (), ou construir o vetor para dimensionar, para garantir que seu vetor tenha elementos suficientes em para armazenar seus dados. do contrário, você corromperá a memória. Isso é verdade para std :: copy () ou memcpy ().
Esta é a razão de usar vector.push_back (), você não pode escrever além do final do vetor.
fonte
Supondo que você saiba o tamanho do item no vetor:
http://www.cppreference.com/wiki/stl/vector/start
fonte