Estou apenas começando a entrar em C ++ e quero pegar alguns bons hábitos. Se eu acabei de alocar uma matriz de tipos int
com o new
operador, como posso inicializá-los todos para 0 sem repetir todos eles? Devo apenas usar memset
? Existe uma maneira "C ++" de fazer isso?
c++
initialization
memory-management
new-operator
dreamlax
fonte
fonte
&vector[0]
.Respostas:
É um recurso surpreendentemente pouco conhecido do C ++ (como evidenciado pelo fato de que ninguém deu isso como resposta ainda), mas na verdade possui uma sintaxe especial para inicializar um array com valor:
Observe que você deve usar os parênteses vazios - não é possível, por exemplo, usar
(0)
ou qualquer outra coisa (é por isso que isso é útil apenas para inicialização de valor).Isso é explicitamente permitido pela ISO C ++ 03 5.3.4 [expr.new] / 15, que diz:
e não restringe os tipos para os quais isso é permitido, enquanto o
(expression-list)
formulário é explicitamente restrito por outras regras na mesma seção, de forma que não permita tipos de matriz.fonte
new int[10] {}
. Você também pode fornecer valores para inicializar com:new int[10] {1,2,3}
Supondo que você realmente deseja uma matriz e não um std :: vector, a "maneira C ++" seria esta
Mas lembre-se de que, na verdade, isso ainda é apenas um loop que atribui cada elemento a 0 (realmente não há outra maneira de fazer isso, exceto uma arquitetura especial com suporte no nível do hardware).
fonte
Há um número de métodos para alocar uma matriz do tipo intrínseco e todos esses métodos estão corretos, apesar de qual escolher, depende ...
Inicialização manual de todos os elementos em loop
Usando a
std::memset
função de<cstring>
Usando o
std::fill_n
algoritmo de<algorithm>
Usando
std::vector
contêinerSe C ++ 0x estiver disponível, usando os recursos da lista do inicializador
fonte
int array[SIZE] ={1,2,3,4,5,6,7};
notação, posso usar avoid rotateArray(int (& input)[SIZE], unsigned int k);
minha declaração de função, o que seria ao usar a primeira convenção? alguma sugestão?std::memset
esteja errado - você passa 10, parece esperar número de bytes - consulte en.cppreference.com/w/cpp/string/byte/memset . (Acho que isso mostra muito bem por isso deve-se evitar tal construção de baixo nível quando possível.)Se a memória que você está alocando for uma classe com um construtor que faz algo útil, o operador new chamará esse construtor e deixará seu objeto inicializado.
Mas se você estiver alocando um POD ou algo que não tenha um construtor que inicialize o estado do objeto, não poderá alocar memória e inicializá-la com o operador new em uma operação. No entanto, você tem várias opções:
1) Use uma variável de pilha. Você pode alocar e inicializar por padrão em uma etapa, assim:
2) use
memset()
. Observe que, se o objeto que você está alocando não for um POD , definir incorretamente é uma má idéia. Um exemplo específico é que, se você configurar uma classe que possui funções virtuais, você explodirá a tabela e deixará seu objeto em um estado inutilizável.3) Muitos sistemas operacionais têm chamadas que fazem o que você deseja - aloque em uma pilha e inicialize os dados em algo. Um exemplo do Windows seria
VirtualAlloc()
4) Geralmente é a melhor opção. Evite ter que gerenciar a memória você mesmo. Você pode usar contêineres STL para fazer praticamente tudo o que faria com a memória bruta, incluindo alocar e inicializar tudo de uma só vez:
fonte
Sim existe:
Use um vetor em vez de uma matriz alocada dinamicamente. Os benefícios incluem não ter que se preocupar em excluir explicitamente a matriz (ela é excluída quando o vetor fica fora do escopo) e também que a memória é excluída automaticamente, mesmo se houver uma exceção lançada.
Edit: Para evitar mais downvotes drive-by de pessoas que não se preocupam em ler os comentários abaixo, devo deixar mais claro que essa resposta não diz que vetor é sempre a resposta certa. Mas com certeza é uma maneira mais C ++ do que "manualmente", certificando-se de excluir uma matriz.
Agora, com o C ++ 11, também existe o std :: array que modela uma matriz de tamanho constante (vetor vs capaz de crescer). Também existe std :: unique_ptr que gerencia uma matriz alocada dinamicamente (que pode ser combinada com a inicialização conforme respondido em outras respostas a esta pergunta). Qualquer uma dessas maneiras é mais C ++ do que manipular manualmente o ponteiro para a matriz, IMHO.
fonte
std::vector
vez de matrizes alocadas dinamicamente? Quais são os benefícios de usar uma matriz sobre um vetor e vice-versa?std::vector
.vector
em qualquer lugar, independentemente do contexto, é chamado "Escrevendo código Java em C ++".std::fill
é uma maneira. Leva dois iteradores e um valor para preencher a região. Esse, ou o loop for, (suponho) seria a maneira mais C ++.Para definir uma matriz de tipos inteiros primitivos como 0 especificamente,
memset
é bom, embora possa levantar sobrancelhas. Considere tambémcalloc
, embora seja um pouco inconveniente usar o C ++ por causa do elenco.Da minha parte, eu quase sempre uso um loop.
(Não gosto de adivinhar as intenções das pessoas, mas é verdade que
std::vector
todas as coisas são iguais, preferível a usarnew[]
.)fonte
você sempre pode usar o memset:
fonte
memset
, mas não tinha certeza se essa era a maneira C ++ de abordar o problema.10 * sizeof( *myArray )
é mais documentado e à prova de alterações do que10 * sizeof( int )
.Normalmente, para listas dinâmicas de itens, você usa a
std::vector
.Geralmente, eu uso o memset ou um loop para alocação dinâmica de memória bruta, dependendo de quão variável eu prevejo que essa área de código seja no futuro.
fonte