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 ++?

user69514
fonte
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;
Michael Mrozek
fonte
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.

Joshua Clayton
fonte
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.

Ben Collins
fonte
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.
Jagannath
fonte
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.

Bóson Z
fonte
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 ().

Eddy Pronk
fonte
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];
Joshua Oliphant
fonte
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];
Tejashree Kudale
fonte
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.

Aadil Imran
fonte
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];

Khuê Phạm
fonte
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
Karthik
fonte
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