Matriz estática frente a matriz dinámica en C ++

91

¿Cuál es la diferencia entre una matriz estática y una matriz dinámica en C ++?

Tengo que hacer una tarea para mi clase y dice que no use matrices estáticas, solo matrices dinámicas. He buscado en el libro y en línea, pero parece que no entiendo.

Pensé que la estática se creaba en tiempo de compilación y dinámica en tiempo de ejecución, pero podría estar confundiendo esto con la asignación de memoria.

¿Puede explicar la diferencia entre matriz estática y matriz dinámica en C ++?

user69514
fuente
1
Estático no es lo contrario de dinámico. O el libro que está usando es terrible o lo está sacando de contexto. Voy a agregar una nueva respuesta a continuación para aclarar esto.
Joshua Clayton
3
Consulte el diagrama de esta pregunta: stackoverflow.com/a/11698458/1143274 Las matrices estáticas no se asignan en la pila ni en el montón.
Evgeni Sergeev
* matriz fija vs matriz dinámica
csguy

Respuestas:

102

Las matrices locales se crean en la pila y tienen una duración de almacenamiento automática; no es necesario administrar la memoria manualmente, pero se destruyen cuando finaliza la función. Tienen necesariamente un tamaño fijo:

int foo[10];

Las matrices creadas con operator new[]tienen una duración de almacenamiento dinámica y se almacenan en el montón (técnicamente la "tienda gratuita"). Pueden tener cualquier tamaño, pero debe asignarlos y liberarlos usted mismo, ya que no forman parte del marco de la pila:

int* foo = new int[10];
delete[] foo;
Michael Mrozek
fuente
18
Esto es correcto, pero solo para ilustrar cómo funciona. Por favor, no haga esto en código real, use un std :: vector en su lugar.
Eddy Pronk
23
@Eddy: Depende de la situación en cuanto a si un vector es necesario
Casebash
6
@Casebash: ¿En qué situación preferirías una matriz? "Siempre deberías preferir usar vectores o deques en lugar de matrices". - Herb Sutter (C ++ más excepcional)
Eddy Pronk
16
@EddyPronk Por razones de fragmentación de la memoria, se puede usar una matriz fija como una especie de grupo. No todos los casos exigen el montón, existen beneficios especiales al usar arreglos basados ​​en pilas. Estás tratando el std :: vector como un martillo de oro, un anti-patrón común.
void.pointer
4
@EddyPronk: Estoy bastante seguro de que Herb Sutter se refería a matrices dinámicas, como las int* foo = new int[N]que tiene para deleteusted mismo y, por lo tanto, tenga cuidado en presencia de excepciones. Las matrices estáticas no tienen estos problemas.
Alexander Malakhov
31

static es una palabra clave en C y C ++, por lo que en lugar de un término descriptivo general, static tiene un significado muy específico cuando se aplica a una variable o matriz. Para agravar la confusión, tiene tres significados distintos dentro de contextos separados. Debido a esto, una matriz estática puede ser fija o dinámica.

Dejame explicar:

El primero es específico de C ++:

  • Un miembro de clase estática es un valor que no se crea una instancia con el constructor ni se elimina con el destructor. Esto significa que el miembro debe inicializarse y mantenerse de alguna otra manera. El miembro estático puede ser punteros inicializados a nulo y luego asignados la primera vez que se llama a un constructor. (Sí, eso sería estático y dinámico)

Dos se heredan de C:

  • dentro de una función, una variable estática es aquella cuya ubicación de memoria se conserva entre llamadas a funciones. Es estático porque se inicializa solo una vez y conserva su valor entre las llamadas a la función (el uso de estática hace que una función no reentrante, es decir, no segura para subprocesos)

  • Las variables estáticas declaradas fuera de las funciones son variables globales a las que solo se puede acceder desde el mismo módulo (archivo de código fuente con cualquier otro # de inclusión)

La pregunta (creo) que quería hacer es cuál es la diferencia entre matrices dinámicas y matrices en tiempo de compilación o fijas. Esa es una pregunta más fácil, las matrices en tiempo de compilación se determinan de antemano (cuando se compila el programa) y son parte de un marco de pila de funciones. Se asignan antes de que se ejecute la función principal. Las matrices dinámicas se asignan en tiempo de ejecución con la palabra clave "new" (o la familia malloc de C) y su tamaño no se conoce de antemano. las asignaciones dinámicas no se limpian automáticamente hasta que el programa deja de ejecutarse.

Joshua Clayton
fuente
4
+1, su respuesta es la más precisa y precisa y debería haber recibido más votos.
Bosón Z
Si declara el tamaño de la matriz con el new[]operador, ¿cómo es que no se conoce el tamaño hasta el tiempo de ejecución? ieint* p = new int[10]
wulfgarpro
"Se asignan antes de que se ejecute la función principal". ¿Por qué asignar las variables de la pila antes de ingresar el bloque relevante?
AlwaysLearning
Las variables de pila (generalmente variables locales en una función) tienen un tamaño y una posición predefinidos dentro de un marco de pila y toda la pila se asigna antes de que se ejecute la función principal, @AlwaysLearning. Cuando se ingresa a un marco de pila mediante la llamada a una función, el puntero de pila se actualiza, pero el nuevo marco de pila está dentro de la pila. No se asignan más pilas. De hecho, demasiadas variables (una matriz gigante, por ejemplo) o demasiadas llamadas a funciones abiertas al mismo tiempo dan como resultado un desbordamiento de pila, por lo que se nombra este sitio.
Joshua Clayton
@JoshuaClayton Creo que esto no puede ser correcto. ¿Cómo puede asignar los marcos de pila (observe el plural) para una función recursiva cuando no sabe cuántas veces se ingresarán?
AlwaysLearning
11

Creo que la semántica que se usa en su clase es confusa. Lo que probablemente significa "estático" es simplemente "tamaño constante", y lo que probablemente significa "dinámico" es "tamaño variable". En ese caso, una matriz de tamaño constante podría verse así:

int x[10];

y uno "dinámico" sería cualquier tipo de estructura que permita aumentar o disminuir el almacenamiento subyacente en tiempo de ejecución. La mayoría de las veces, la std::vectorclase de la biblioteca estándar de C ++ será suficiente. Úselo así:

std::vector<int> x(10); // this starts with 10 elements, but the vector can be resized.

std::vectorha operator[]definido, por lo que puede usarlo con la misma semántica que una matriz.

Ben Collins
fuente
1
Creo que está bastante claro que por "matriz dinámica" simplemente se refieren a una matriz asignada dinámicamente (es decir, una en la que el tamaño se puede especificar dinámicamente, en tiempo de ejecución). Me gustanew int[10]
jalf
@jalf: Estaba más preocupado por el término 'estático'. Prefiero llamar a una "matriz dinámica" una matriz de tamaño variable o asignada en aras de la coherencia.
Ben Collins
Buen punto porque una matriz estática podría ser automática e implementada en la pila o ser global e implementada en una sección de datos. Ambos son estáticos pero internamente el código que accede a ellos puede ser muy diferente.
Bosón Z
9

A las matrices estáticas se les asigna memoria en tiempo de compilación y la memoria se asigna en la pila. Considerando que, a las matrices dinámicas se les asigna memoria en el tiempo de ejecución y la memoria se asigna desde el montón.

int arr[] = { 1, 3, 4 }; // static integer array.   
int* arr = new int[3]; // dynamic integer array.
Jagannath
fuente
4
Una matriz global es una matriz estática y se implementa en una sección de datos y no desde la pila.
Bosón Z
8

Es importante tener definiciones claras de lo que significan los términos. Desafortunadamente, parece haber múltiples definiciones de lo que significan matrices estáticas y dinámicas.

Las variables estáticas son variables definidas mediante la asignación de memoria estática . Este es un concepto general independiente de C / C ++. En C / C ++ podemos crear variables estáticas con alcance global, de archivo o local como este:

int x[10]; //static array with global scope
static int y[10]; //static array with file scope
foo() {
    static int z[10]; //static array with local scope

Las variables automáticas generalmente se implementan mediante la asignación de memoria basada en pilas . Se puede crear una matriz automática en C / C ++ como esta:

foo() {
    int w[10]; //automatic array

Lo que estos arreglos, x, y, zy wtienen en común es que el tamaño de cada uno de ellos es fijo y se define en el momento de la compilación.

Una de las razones por las que es importante comprender la distinción entre una matriz automática y una matriz estática es que el almacenamiento estático generalmente se implementa en la sección de datos (o sección BSS ) de un archivo de objeto y el compilador puede usar direcciones absolutas para acceder a las matrices. lo cual es imposible con el almacenamiento basado en pilas.

Lo que generalmente se entiende por matriz dinámica no es una que se pueda cambiar de tamaño, sino una implementada mediante la asignación de memoria dinámica con un tamaño fijo determinado en tiempo de ejecución. En C ++ esto se hace usando el newoperador .

foo() {
   int *d = new int[n]; //dynamically allocated array with size n     

Pero es posible crear una matriz automática con un tamaño de corrección definido en tiempo de ejecución usando alloca:

foo() {
    int *s = (int*)alloca(n*sizeof(int))

Para una verdadera matriz dinámica, se debe usar algo como std::vectoren C ++ (o una matriz de longitud variable en C ).

¿Qué significaba la asignación en la pregunta del OP? Creo que está claro que lo que se quería no era una matriz estática o automática, sino una que usaba la asignación de memoria dinámica usando el newoperador o una matriz de tamaño no fijo usando, por ejemplo std::vector.

Bosón Z
fuente
3

Creo que en este contexto significa que es estático en el sentido de que el tamaño es fijo. Utilice std :: vector. Tiene una función resize ().

Eddy Pronk
fuente
2

Podría tener una matriz pseudodinámica donde el tamaño lo establece el usuario en tiempo de ejecución, pero luego se fija después de eso.

int size;
cin >> size;
int dynamicArray[size];
Joshua Oliphant
fuente
No forma parte del estándar C ++ (en C99 y como una extensión del compilador para gcc).
crashmstr
1

Matriz estática :

  1. A las matrices estáticas se les asigna memoria en tiempo de compilación.
  2. El tamaño es fijo.
  3. Ubicado en el espacio de memoria de la pila.
  4. P.ej. : int matriz [10]; // matriz de tamaño 10

Matriz dinámica:

  1. La memoria se asigna en tiempo de ejecución.
  2. El tamaño no es fijo.
  3. Ubicado en el espacio de memoria del montón.
  4. P.ej. : int * matriz = nuevo int [10];
Tejashree Kudale
fuente
0

Sí, a la derecha, la matriz estática se crea en el tiempo de compilación, mientras que la matriz dinámica se crea en el tiempo de ejecución. Mientras que la diferencia en lo que respecta a sus ubicaciones de memoria, las estáticas se ubican en la pila y las dinámicas se crean en el montón. Todo lo que se encuentra en el montón necesita la administración de la memoria hasta que esté presente un recolector de basura como en el caso de .net framework, de lo contrario existe el riesgo de pérdida de memoria.

Aadil Imran
fuente
0

Matriz estática: Eficiencia. No se requiere asignación dinámica o desasignación.

Las matrices declaradas en C, C ++ en función, incluido el modificador estático, son estáticas. Ejemplo: static int foo [5];

Khuê Phạm
fuente
1
@admdrew, eso es cierto, pero la pregunta nunca fue bien respondida. La mejor respuesta es la respuesta de Joshua Clayton, pero creo que una mejor respuesta es esta stackoverflow.com/questions/17775066/…
Z boson
@Zboson Es bueno saberlo, gracias. Je y yo nos dimos cuenta de que hice ese comentario hace casi un año.
admdrew
-3

Meens arbitrarios estáticos con elementos que se dan en el lado de la matriz

Meens arrarios dinámicos sin ceder elementos en el lado de la matriz

ejemplo:

     char a[10]; //static array
       char a[];  //dynamic array
karthik
fuente
Creo que dijo correcto. Cuando le das una longitud exacta a la matriz, es una matriz estática y cuando no le das la longitud, es una matriz dinámica. pero como no sabe escribir en inglés, es por eso que la gente anota esta respuesta.
muhammad tayyab