Matriz estática vs. matriz dinâmica em C ++


93

Qual é a diferença entre uma matriz estática e uma matriz dinâmica em C ++?

Eu tenho que fazer uma tarefa para minha classe e diz para não usar arrays estáticos, apenas arrays dinâmicos. Procurei no livro e online, mas não pareço entender.

Achei que a estática foi criada em tempo de compilação e dinâmica em tempo de execução, mas posso estar confundindo isso com alocação de memória.

Você pode explicar a diferença entre array estático e array dinâmico em C ++?


1
Estático não é o oposto de dinâmico. Ou o livro que você está usando é terrível ou o está tirando do contexto. Vou adicionar uma nova resposta abaixo para esclarecer isso.
— Joshua Clayton

3
Consulte o diagrama nesta pergunta: stackoverflow.com/a/11698458/1143274 As matrizes estáticas não são alocadas na pilha ou no heap.
— Evgeni Sergeev

* array fixo vs array dinâmico
— csguy

Respostas:


106

Os arrays locais são criados na pilha e têm duração de armazenamento automática - você não precisa gerenciar a memória manualmente, mas são destruídos quando a função em que estão encerrados. Eles têm necessariamente um tamanho fixo:

int foo[10];

Os arrays criados com operator new[]têm duração de armazenamento dinâmico e são armazenados no heap (tecnicamente, o "armazenamento gratuito"). Eles podem ter qualquer tamanho, mas você mesmo precisa alocá-los e liberá-los, pois não fazem parte do quadro de pilha:

int* foo = new int[10];
delete[] foo;

18
Isso está correto, mas apenas para ilustrar como funciona. Por favor, não faça isso em código real, mas use um std :: vector ao invés.
— Eddy Pronk de

23
@ Eddy: Depende da situação se um vetor é necessário
— Casebash

6
@Casebash: Em que situação você prefere um array? "Você deve sempre preferir usar vetores ou deques em vez de matrizes." - Herb Sutter (C ++ mais excepcional)
— Eddy Pronk de

16
@EddyPronk Por motivos de fragmentação de memória, pode-se usar um array fixo como uma espécie de pool. Nem todo caso exige o heap, há benefícios especiais em usar matrizes baseadas em pilha. Você está tratando o std :: vector como um martelo dourado, um anti-padrão comum.
— void.pointer de

4
@EddyPronk: Tenho certeza de que Herb Sutter se referia a matrizes dinâmicas, como as int* foo = new int[N]que você tem para deletesi mesmo e, portanto, tome cuidado na presença de exceções. Matrizes estáticas não têm esses problemas.
— Alexander Malakhov

33

static é uma palavra-chave em C e C ++, portanto, em vez de um termo descritivo geral, static tem um significado muito específico quando aplicado a uma variável ou array. Para aumentar a confusão, ele tem três significados distintos em contextos separados. Por causa disso, uma matriz estática pode ser fixa ou dinâmica.

Deixe-me explicar:

O primeiro é específico do C ++:

  • Um membro de classe estático é um valor que não é instanciado com o construtor ou excluído com o destruidor. Isso significa que o membro deve ser inicializado e mantido de alguma outra maneira. O membro estático pode ser ponteiros inicializados como nulos e então alocados na primeira vez que um construtor é chamado. (Sim, isso seria estático e dinâmico)

Dois são herdados de C:

  • dentro de uma função, uma variável estática é aquela cuja localização na memória é preservada entre as chamadas de função. É estático porque é inicializado apenas uma vez e retém seu valor entre as chamadas de função (o uso de estática torna uma função não reentrante, ou seja, não threadsafe)

  • variáveis ​​estáticas declaradas fora das funções são variáveis ​​globais que só podem ser acessadas de dentro do mesmo módulo (arquivo de código-fonte com qualquer outro # include)

A questão (eu acho) que você quis fazer é qual a diferença entre arrays dinâmicos e arrays fixos ou em tempo de compilação. Essa é uma pergunta mais fácil, os arrays de tempo de compilação são determinados antecipadamente (quando o programa é compilado) e fazem parte de um quadro de pilha de funções. Eles são alocados antes da execução da função principal. arrays dinâmicos são alocados em tempo de execução com a palavra-chave "new" (ou a família malloc de C) e seu tamanho não é conhecido com antecedência. as alocações dinâmicas não são limpas automaticamente até que o programa pare de ser executado.


4
+1, sua resposta é a mais exata e precisa e deveria ter recebido mais votos.
— Bóson Z de

Se você declarar o tamanho da matriz com o new[]operador, como é que o tamanho não é conhecido até o tempo de execução? ieint* p = new int[10]
— wulfgarpro

"Eles são alocados antes da execução da função principal." Por que alocar as variáveis ​​da pilha antes que o bloco relevante seja inserido?
— AlwaysLearning

Variáveis ​​de pilha (geralmente variáveis ​​locais em uma função) têm um tamanho e posição predefinidos dentro de uma estrutura de pilha e toda a pilha é alocada antes da execução da função principal, @AlwaysLearning. Ao inserir um quadro de pilha por meio da chamada de função, o ponteiro da pilha é atualizado, mas o novo quadro de pilha está dentro da pilha. Nenhuma pilha mais é alocada. Na verdade, variáveis ​​muito grandes (uma matriz gigante, por exemplo) ou muitas chamadas de função abertas ao mesmo tempo resultam em um estouro de pilha, para o qual este site é nomeado.
— Joshua Clayton

@JoshuaClayton Acho que isso não pode estar correto. Como você pode alocar os frames da pilha (observe o plural) para uma função recursiva quando você não sabe quantas vezes ela será inserida?
— AlwaysLearning

11

Eu acho que a semântica sendo usada em sua aula é confusa. O que provavelmente se entende por 'estático' é simplesmente "tamanho constante", e o que provavelmente se entende por "dinâmico" é "tamanho variável". Nesse caso, uma matriz de tamanho constante pode ter a seguinte aparência:

int x[10];

e um "dinâmico" seria qualquer tipo de estrutura que permite que o armazenamento subjacente seja aumentado ou diminuído no tempo de execução. Na maioria das vezes, a std::vectorclasse da biblioteca padrão C ++ será suficiente. Use-o assim:

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

std::vectorfoi operator[]definido, para que você possa usá-lo com a mesma semântica como uma matriz.


1
Acho que está bastante claro que por "matriz dinâmica" eles simplesmente significam uma matriz alocada dinamicamente (ou seja, uma em que o tamanho pode ser especificado dinamicamente, em tempo de execução). Likenew int[10]
— jalf de

@jalf: Eu estava mais preocupado com o termo 'estático'. Eu prefiro chamar uma "matriz dinâmica" de uma matriz alocada ou de tamanho variável por uma questão de consistência.
— Ben Collins,

Um bom ponto porque uma matriz estática pode ser automática e implementada na pilha ou ser global e implementada em uma seção de dados. Ambos são estáticos, mas internamente o código que os acessa pode ser muito diferente.
— Bóson Z de

9

Matrizes estáticas são alocadas na memória em tempo de compilação e a memória é alocada na pilha. Considerando que, os arrays dinâmicos são alocados memória no tempo de execução e a memória é alocada do heap.

int arr[] = { 1, 3, 4 }; // static integer array.   
int* arr = new int[3]; // dynamic integer array.

6
Uma matriz global é uma matriz estática e é implementada em uma seção de dados e não da pilha.
— Bóson Z de

9

É importante ter definições claras do significado dos termos. Infelizmente, parece haver várias definições do que significam os arrays estáticos e dinâmicos.

Variáveis ​​estáticas são variáveis ​​definidas usando alocação de memória estática . Este é um conceito geral independente de C / C ++. Em C / C ++, podemos criar variáveis ​​estáticas com escopo global, de arquivo ou 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

Variáveis ​​automáticas são geralmente implementadas usando alocação de memória baseada em pilha . Uma matriz automática pode ser criada em C / C ++ assim:

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

O que esses arrays, x, y, ze wtêm em comum é que o tamanho de cada um deles é fixo e definido em tempo de compilação.

Uma das razões pelas quais é importante entender a distinção entre um array automático e um array estático é que o armazenamento estático é geralmente implementado na seção de dados (ou seção BSS ) de um arquivo de objeto e o compilador pode usar endereços absolutos para acessar os arrays o que é impossível com armazenamento baseado em pilha.

O que geralmente significa um array dinâmico não é aquele que pode ser redimensionado, mas um implementado usando alocação de memória dinâmica com um tamanho fixo determinado em tempo de execução. Em C ++, isso é feito usando o newoperador .

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

Mas é possível criar uma matriz automática com um tamanho de correção definido em tempo de execução usando alloca:

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

Para um verdadeiro array dinâmico, deve-se usar algo como std::vectorem C ++ (ou um array de comprimento variável em C ).

O que significava a atribuição na pergunta do OP? Acho que está claro que o que se queria não era um array estático ou automático, mas um que usasse alocação de memória dinâmica usando o newoperador ou um array de tamanho não fixo usando, por exemplo std::vector.


3

Acho que, neste contexto, significa que é estático no sentido de que o tamanho é fixo. Use std :: vector. Ele tem uma função resize ().


2

Você poderia ter uma matriz pseudo dinâmica em que o tamanho é definido pelo usuário em tempo de execução, mas é corrigido depois disso.

int size;
cin >> size;
int dynamicArray[size];

Não faz parte do C ++ padrão (em C99 e como uma extensão do compilador para gcc).
— crashmstr de

1

Matriz estática :

  1. Matrizes estáticas são alocadas na memória em tempo de compilação.
  2. O tamanho é fixo.
  3. Localizado no espaço de memória da pilha.
  4. Por exemplo. : int array [10]; // array de tamanho 10

Matriz dinâmica:

  1. A memória é alocada em tempo de execução.
  2. O tamanho não é fixo.
  3. Localizado no espaço de memória Heap.
  4. Por exemplo. : int * array = new int [10];

0

Sim, certo, o array estático é criado no momento da compilação, enquanto o array dinâmico é criado no tempo de execução. No que diz respeito à diferença, no que diz respeito às localizações de memória, os estáticos estão localizados na pilha e os dinâmicos são criados no heap. Tudo o que fica localizado na pilha precisa do gerenciamento de memória até e a menos que o coletor de lixo, como no caso da estrutura .net, esteja presente, caso contrário, há o risco de vazamento de memória.


0

Matriz estática: Eficiência. Nenhuma alocação dinâmica ou desalocação é necessária.

Matrizes declaradas em C, C ++ em função, incluindo modificador estático, são estáticas. Exemplo: static int foo [5];


1
@admdrew, isso é verdade, mas a pergunta nunca foi respondida bem. A melhor resposta é a de Joshua Clayton, mas acho que uma resposta melhor é esta stackoverflow.com/questions/17775066/…
— Bóson Z

@Zboson Bom saber, obrigado. Heh e eu acabamos de perceber que fiz esse comentário há quase um ano.
— Admdrew em

-3

estática arrary meens com distribuição de elementos ao lado da matriz

arrary meens dinâmicos sem ceder elementos ao lado da matriz

exemplo:

     char a[10]; //static array
       char a[];  //dynamic array

Eu acho que ele disse correto. Quando você determina o comprimento exato para o array, ele é um array estático e quando você não dá o comprimento é um array dinâmico. mas como ele não sabe escrever em inglês é por isso que as pessoas marcam esta resposta.
— muhammad tayyab de
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.