2010-09-21 12 views
12

En C++, puedo inicializar estáticamente una matriz, por ejemplo .:¿Hay alguna manera de inicializar estáticamente una matriz asignada dinámicamente en C++?

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

¿Hay una manera fácil para inicializar una matriz asignada dinámicamente a un conjunto de valores inmediatos?

int *p = new int[3]; 
p = { 1, 2, 3 }; // syntax error 

... ¿o tengo que copiar estos valores de forma manual?

+0

¿A qué se opone? La necesidad de escribir código para inicializar un vector? ¿El tiempo que lleva copiar? Tenga en cuenta que cualquier truco del compilador para inicializar una matriz dinámicamente asignada implicaría la misma copia, ya que no es posible garantizar que la memoria asignada tenga los contenidos exactos correctos. –

+0

Si el rendimiento es esencial, ¿por qué está asignando dinámicamente? ¿Por qué la indirección a través de un puntero? Como está "inicializando estáticamente" la matriz de todos modos, seguramente las dimensiones de las matrices se conocen en tiempo de compilación. – fredoverflow

+0

No me opongo a nada, solo pregunto. Estoy usando una clase de matriz propia que almacena datos en una matriz asignada dinámicamente y pensé que sería bueno si pudiera inicializar esa matriz sin copiar los datos manualmente. :) – neuviemeporte

Respuesta

27

Usted puede en C++ 0x:

int* p = new int[3] { 1, 2, 3 }; 
... 
delete[] p; 

Pero me gustaría vectores mejor:

std::vector<int> v { 1, 2, 3 }; 

Si usted no tiene un compilador de C++ 0x, impulso puede ayudar a:

#include <boost/assign/list_of.hpp> 
using boost::assign::list_of; 

vector<int> v = list_of(1)(2)(3); 
+5

'+ 1' para' std :: vector'. ¿Qué razón hay para seguir usando tus propias matrices dinámicas? – sbi

+0

@sbi De acuerdo, no parece que haya mucho uso para enrollar el suyo cuando los vectores son mucho más agradables. – EricBoersma

+0

@sbi - acceder a elementos de matriz nativa es más rápido que hacer lo mismo con un vector. Probado. – Poni

1

No, no puede inicializar una matriz creada dinámicamente de la misma manera.

La mayoría de las veces se encontrará utilizando la asignación dinámica en situaciones donde la inicialización estática en realidad no tiene sentido de todos modos. Por ejemplo, cuando tienes matrices que contienen miles de elementos. Entonces esto no suele ser un gran problema.

8

tiene que asignar cada elemento de la matriz dinámica de forma explícita (por ejemplo, en una a favor o en bucle while)

Sin embargo la sintaxis int *p = new int [3](); hace inicializar todos los elementos a 0 (valor de inicialización $ 8,5/5)

-1

Nunca oído hablar de tal cosa es posible, que sería bueno tener.

Tenga en cuenta que inicializando la matriz en el código de esa manera

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

..... sólo le gana más fácil la escritura de código y no el rendimiento. Después de todo, la CPU hará el trabajo de asignar valores a la matriz, de cualquier forma que lo haga.

+0

Esa línea no genera ningún código ... es una inicialización en tiempo de compilación. – joeking

1

mediante la variable helper:

const int p_data[] = {1, 2, 3}; 
int* p = (int*)memcpy(new int[3], p_data, sizeof(p_data)); 

o, una línea

int p_data[] = {1, 2, 3}, *p = (int*)memcpy(new int[3], p_data, sizeof(p_data)); 
+3

Como regla general (y es un buen hábito para entrar), no debe asignar dinámicamente un objeto en una llamada a función (es decir, nunca debe llamar 'new' en un argumento a una función). La razón es que el orden de evaluación de los argumentos de la función no está especificado, por lo que podría terminar asignando dinámicamente la memoria, luego la evaluación de otro argumento arrojaría una excepción, luego se filtró ese objeto asignado dinámicamente. [Herb Sutter tiene más] (http://www.gotw.ca/gotw/056.htm). –

+0

+1 Aunque esto es un poco críptico y solo funciona para POD. – fredoverflow

+1

James McNellis, las reglas generales son solo _general_ reglas. Y ellos tienen una explicación para asegurarse de que la regla coincida con el caso. En este caso, todo está bien. – Abyx

4

Para evitar interminables push_backs, por lo general inicializar un tr1::array y crear un std::vector (o cualquier otro recipiente std contenedor) de el resultado;

const std::tr1::array<T, 6> values = {T(1), T(2), T(3), T(4), T(5), T(6)}; 
std::vector <T> vec(values.begin(), values.end()); 

La única molestia aquí es que debe proporcionar el número de valores explícitamente.

Por supuesto, esto se puede hacer sin usar un tr1::array;

const T values[] = {T(1), T(2), T(3), T(4), T(5), T(6)}; 
std::vector <T> vec(&values[0], &values[sizeof(values)/sizeof(values[0])]); 

A través de que no tiene que proporcionar explícitamente el número de elementos, prefiero la primera versión.

+0

+1 ¡Solución perfecta! – fredoverflow

Cuestiones relacionadas