2010-07-24 4 views
6

tengo el siguiente código:C++ int a [n] de trabajo en g ++ pero no con VS2008

... 
int n; 
cin >> n; 
int numbers[n]; 
... 

Se compiló con NetBeans en Mac usando g ++ (creo) y no compilar usando VS2008 en Windows. ¿Por qué es tan difícil hacer que funcione con cada compilador? El tamaño de la matriz se conoce antes de asignarlo.

EDIT: Sé de std::vector. En realidad, esto era parte de una tarea y comencé a trabajar en un Mac, luego llegué a casa y me sorprendió que no funcionara en VS2008. Gracias por todas las respuestas. Pero todavía encuentro lógico que si el compilador puede generar algún código como alloc(123) donde el valor 123 está codificado, ¿por qué no puede generar algo como alloc(n) donde obtienes n desde una dirección de memoria que contiene un int n o algo así. Simplemente parece más lógico permitir algo así por defecto.

+4

¿por qué no utilizar algunas cosas reales de cpp como 'std :: vector ' para eso –

+1

@RC: ¡Es una buena respuesta, que sea real! –

+1

@Drew: hecho;) gracias –

Respuesta

16

Aunque se conoce el tamaño de la matriz antes de asignarla, aún no se conoce hasta el tiempo de ejecución. Esto se conoce como matriz de longitud variable (VLA) y es un C99ism, soportado en g ++ por una extensión que está habilitada por defecto. Para ser explícito, esto no cumple con C++ 98/03, y por lo tanto, Visual C++ está en su derecho de rechazarlo.

Si realmente desea el tamaño dinámico en tiempo de ejecución, asigne en el montón (a través de nuevo []). Eso funcionará en todas partes y, como beneficio adicional, lo protegerá de desbordamientos de pila.

+7

En realidad, no use 'new []'. Use 'std :: vector'. – GManNickG

+0

@ GMan - ¡De todo corazón estoy de acuerdo! En mi prisa me olvidé de mencionar esa opción, pero no quiero recoger la respuesta de RC en este momento. :) –

+0

Aunque he tenido que solucionar esta falta, al implementar los algoritmos de inserción/eliminación de la estructura de datos. Estos son muy utilizados, incluso en bucles internos, por lo que definitivamente se trata de hotspots de rendimiento.Necesitaba construir un "plan" (no empieces a cambiar nodos hasta que sepas que la operación tendrá éxito - asegura la autoconsistencia en caso de falla). Al final utilicé una lista enlazada en la pila, construí un ítem a la vez usando llamadas recursivas (haciendo un esfuerzo para minimizar los gastos generales de llamadas). Un VLA probablemente habría sido más fácil. – Steve314

12

Porque el tamaño de una matriz debe ser una constante de tiempo de compilación en C++ estándar (véase 8.3.4 §1).

1

Soporte para VLA no está presente en Visual Studio 2008.

+7

O en C++ en absoluto. – GManNickG

12

por qué no usar un poco de materia verdadera CPP como std::vector<int> para ese Algo

2

similares pueden hacerse con Ne

int* numbers = (int*)alloca(n * sizeof(int)); // equivalent to int numbers[n] 

esto no es función recomendada, pero si se usa con cuidado, da exactamente el mismo resultado.

+4

Y con una entrada cuidadosamente elaborada, el usuario puede desbordar la pila y anotar una para los malos. –

+0

@Franci, ¿no tiene nada mejor que hacer que diseñar la "entrada cuidadosamente diseñada" para este programa en particular? :) Mejor intentar http://www.crackmes.de – ruslik

+0

Hay una diferencia importante entre VLA y alloca(). VLA persiste en su alcance de declaración, mientras que el bloque alloca() persiste para el alcance de la * función *. Declarar un VLA en un cuerpo de bucle utiliza, por lo tanto, menos stack que haciendo una alloca en el cuerpo. Entonces, si aprende acerca del tamaño de matriz requerido en el ciclo, alloca podría no funcionar para usted. –

2

Por libro, la dimensión del conjunto debe ser una expresión constante cuyo valor sea mayor o igual a uno. Expresión constante en el sentido constantes literales integrales, enumeradores o objetos const de tipo integral que se inicializan a partir de expresiones const. Una variable no const cuyo valor no se conoce hasta que el tiempo de ejecución no pueda usarse para especificar la dimensión de una matriz.

Pero la versión del compilador que uso permite el permite la forma que usted mencionó.

Cuestiones relacionadas