bidimensional - new int c++
¿Por qué no hay una matriz de tamaño variable en la pila? (7)
Debido a que en C ++, una matriz estática necesita un tamaño constante estático, por lo que el idioma no lo permite. Tenga en cuenta que C99 admite vararrays en la pila, y algunas implementaciones lo admiten en C ++, así como en una extensión.
Realmente no entiendo por qué no puedo tener una matriz de tamaño variable en la pila, así que algo como
foo(int n) {
int a[n];
}
Como entiendo la pila (-segmento) de parte del segmento de datos y por lo tanto no es de "tamaño constante".
Intentaré explicar esto con un ejemplo:
Digamos que tienes esta función:
int myFunc() {
int n = 16;
int arr[n];
int k = 1;
}
Cuando el programa se ejecuta, establece las variables de esta manera en la pila:
- n @relative addr 0
- arr[16] @relative addr 4
- k @relative addr 64
TOTAL SIZE: 68 bytes
Digamos que quiero cambiar el tamaño de arr a 4 elementos. Voy a hacer:
delete arr;
arr = new int[4];
Ahora: si dejo la pila de esta manera, la pila tendrá agujeros de espacio no utilizado. Así que lo más inteligente es mover todas las variables de un lugar a otro en la pila y volver a calcular sus posiciones. Pero nos falta algo: C ++ no establece las posiciones sobre la marcha, se hace solo una vez, cuando compilas el programa. ¿Por qué? Es sencillo: porque no hay una necesidad real de tener objetos de tamaño variable en la pila, y porque tenerlos ralentizaría todos los programas al asignar / reasignar espacio de pila.
Este no es el único problema, hay otro, incluso más grande: cuando asigna una matriz, decide cuánto espacio tomará y el compilador puede avisarle si excede el espacio disponible, en lugar de permitir que el programa asigne variables El tamaño de las matrices en su pila, está abriendo brechas en la seguridad, ya que hace que todos los programas que usan este tipo de método sean vulnerables a los desbordamientos de pila.
Las pilas son bastante pequeñas y sus tamaños pueden variar considerablemente según la arquitectura. El problema es que es bastante fácil de "sobre-asignar" y causar una falla de seguridad o escritura en la memoria de otra persona. Mientras tanto, las soluciones al problema (por ejemplo, vector
) han existido durante mucho tiempo.
FWIW, leí a Stroustrup decir que él no los quería , pero no sé en qué entrevista estaba.
Porque la especificación del lenguaje lo dice. Nada más importa (y explicar con segmentos es terriblemente incorrecto por diferentes razones).
Respuesta simple: porque no está definido en el estándar C ++.
Respuesta no tan simple: porque en ese caso nadie propuso que algo se comportara de manera coherente para C ++. Desde los estándares POV no hay pila, podría implementarse de manera totalmente diferente. C99 tiene VLA, pero parecen ser tan complejos de implementar que gcc solo terminó la implementación en 4.6. No creo que mucha gente quiera proponer algo para C ++ y ver a los fabricantes de compiladores luchar por ello durante muchos años.
Las matrices de longitud variable (VLA) no están permitidas en C ++ según el estándar de C ++.
Muchos compiladores, incluido gcc, los admiten como una extensión del compilador, pero es importante tener en cuenta que cualquier código que use dicha extensión no es portátil.
C ++ proporciona std::vector para implementar una funcionalidad similar a VLA .
Hubo una proposal para introducir matrices de longitud variable en C ++ 11, pero finalmente se eliminó, ya que necesitaría grandes cambios en el sistema de tipos en C ++. La ventaja de poder crear pequeños arreglos en la pila sin desperdiciar espacio o llamar a los constructores para los elementos no utilizados no se consideró lo suficientemente importante para grandes cambios en el sistema de tipo C ++.
Tenga en cuenta que la propuesta fue rechazada y lo siguiente ya no es cierto. Aunque puede ser revivido para una versión futura de C ++.
El VLA como se describe en N3639 ha sido aceptado en la reunión de Bristol y se convertirá en parte de C ++ 14, así como en una contraparte de biblioteca "dynarray". Entonces, al usar el compilador con soporte para C ++ 14 podemos comenzar a escribir algo como:
void func(int n)
{
int arr[n];
}
O usa dinarray:
#include <dynarray>
void func(int n)
{
std::dynarray<int> arr(n);
}