2010-12-31 12 views
10

¿Cómo inicio manualmente los valores en la matriz en el montón? Si la matriz es variable local (en la pila), se puede hacer de manera muy elegante y fácil, así:Inicialización de la matriz en el montón

int myArray[3] = {1,2,3}; 

Desafortunadamente, siguiente código

int * myArray = new int[3]; 
myArray = {1,2,3}; 

da salida a un error de compilación

error: expected primary-expression before ‘{’ token 
error: expected `;' before ‘{’ token 

¿Tengo que usar ciclo, o no tan elegante manera de esta manera?

myArray[0] = 1; 
myArray[1] = 2; 
myArray[2] = 3; 
+0

por el aspecto de su ejemplo, desea completar los elementos de la matriz 0 .. N, con los valores 1 .. N + 1. Un ciclo for lo haría muy bien. ¿Cuál es tu intención real? – EvilTeach

Respuesta

3

Esto es interesante: Pushing an array into a vector

Sin embargo, si eso no lo hacen por que pruebe lo siguiente:

#include <algorithm> 
... 


const int length = 32; 

int stack_array[length] = { 0 ,32, 54, ... } 
int* array = new int[length]; 

std::copy(array, array + length, &stack_array[0]); 
+0

Ha cometido un error, debe ser 'std :: copy (stack_array, stack_array + 5, y matriz [0]);' – qed

+0

VLA (matriz de longitud variable) no es parte de C++ estándar –

+0

VLAs en C++ por lo -1 – cat

3

Puede definir matriz constante, como myConstArray [] = {1, 2, 3} y hacer memcpy después de nuevo int [3].

+5

de manera más general, use std :: copy para copiar objetos en lugar de patrones de bits. –

+0

Desafortunadamente, esto es ineficiente en el mejor de los casos, e imposible en el peor (si el tipo es una clase sin copia/asignación). – Yttrill

+0

Con el tipo que es una clase sin copia/asignación, sería imposible usar matriz constante en absoluto. –

2

{1,2,3} es una sintaxis muy limitada, específica para la inicialización de la estructura POD (al parecer, la matriz de estilo C también se consideró). Lo único que puede hacer es como int x[] = {1,2,3}; o int x[3] = {1,2,3};, pero no puede hacer ni int x[3]; x={1,2,3}; ni usar {1,2,3} en ningún otro lugar.

Si está haciendo C++, es preferible usar algo como std :: vector en lugar de matrices de estilo C, ya que se consideran peligrosos; por ejemplo, no puede conocer su tamaño y debe eliminarlos con delete[] , no es un delete normal. Sin embargo, con std :: vector aún tendrá el mismo problema de inicialización. Si utilicé tal inicialización mucho, probablemente crearía una asignación de macro a una variable local ficticia y luego copiaría la memoria al destino.

EDIT: También puede hacerlo de esta manera (std :: vector sigue siendo preferible):

int* NewArray(int v1, int v2, int v3) { /* allocate and initialize */ } 
int* p = NewArray(1,2,3); 

pero entonces usted tendrá que reemplazar la función con un número diferente de argumentos, o utilizar va_arg que es , de nuevo, inseguro.

EDIT2: Mi respuesta solo es válida para C++ 03, ya que otras personas mencionaron que C++ 0x tiene algunas mejoras en esto.

0
estándar

C++ 0x ha tipo especial llamado initializer_list y la sintaxis especial para ello (tipo de expresión {1, 2, 3} es std::initializer_list<int>). std::vector y std::array tienen constructores de ella, por lo que puede escribir vector<int> v = {1, 2, 3}.

No hay una buena solución en C++ 98/C++ 03.

0

Si desea una respuesta general que funciona para todos tipos, a continuación, lo que se hace es:

  1. malloc() o el operador new() para crear una matriz de almacenamiento sin inicializar de la longitud correcta , calculado por nelts * sizeof (T)

  2. Haga una matriz que conste del argumento de un constructor para cada elemento.

  3. Aplicar el constructor en forma de colocación a cada elemento utilizando el argumento correspondiente.

Esto solo funciona si el mismo constructor sirve para cada elemento. De lo contrario, necesitará una estructura de datos y un algoritmo más complicados para elegir el constructor adecuado para cada elemento.

Un caso especial de esto es utilizar una matriz de los elementos reales y utilizar el constructor de copia, y un caso especial de eso es cuando el tipo es un POD y puede usar memcpy para construir el lote de una vez.

Si el constructor toma dos argumentos, tendrá que escribir un procedimiento de iniciador (contenedor). Por ejemplo:

pair<double> init_data[] = {make_pair(1.0,0.0), make_pair(3.0,4.0)}; 
void init(void *p, pair<double> d) { new (p) complex(d.first, d.second); } 

y utilícelo en lugar de simplemente nuevo (p).

Cuestiones relacionadas