Array statico vs array dinamico in C ++


91

Qual è la differenza tra un array statico e un array dinamico in C ++?

Devo fare un compito per la mia classe e dice di non usare array statici, solo array dinamici. Ho cercato nel libro e online, ma non mi sembra di capire.

Pensavo che statico fosse stato creato in fase di compilazione e dinamico in fase di esecuzione, ma potrei confonderlo con l'allocazione della memoria.

Puoi spiegare la differenza tra array statico e array dinamico in C ++?


1
Statico non è l'opposto di dinamico. O il libro che stai usando è terribile o lo stai estrapolando dal contesto. Aggiungerò una nuova risposta di seguito per chiarire si spera.
Joshua Clayton

3
Vedere il diagramma in questa domanda: stackoverflow.com/a/11698458/1143274 Gli array statici non sono allocati nello stack o nell'heap.
Evgeni Sergeev

* array fisso vs array dinamico
csguy

Risposte:


102

Gli array locali vengono creati nello stack e hanno una durata di archiviazione automatica: non è necessario gestire manualmente la memoria, ma vengono distrutti quando la funzione in cui si trovano termina. Hanno necessariamente una dimensione fissa:

int foo[10];

Gli array creati con operator new[]hanno una durata di archiviazione dinamica e vengono archiviati nell'heap (tecnicamente "l'archivio gratuito"). Possono avere qualsiasi dimensione, ma è necessario assegnarli e liberarli da soli poiché non fanno parte dello stack frame:

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

18
Questo è corretto, ma solo per illustrare come funziona. Per favore, non farlo in codice reale ma usa invece uno std :: vector.
Eddy Pronk

23
@Eddy: Dipende dalla situazione se è necessario un vettore
Casebash

6
@Casebash: in quale situazione preferiresti un array? "Dovresti sempre preferire usare vettori o deques invece di array." - Herb Sutter (C ++ più eccezionale)
Eddy Pronk il

16
@EddyPronk Per motivi di frammentazione della memoria è possibile utilizzare un array fisso come una sorta di pool. Non tutti i casi richiedono l'heap, ci sono vantaggi speciali nell'utilizzo di array basati su stack. Stai trattando lo std :: vector come un martello d'oro, un comune anti-pattern.
void.pointer

4
@ EddyPronk: Sono abbastanza sicuro che Herb Sutter intendesse array dinamici, come quelli int* foo = new int[N]che hai per deletete stesso e quindi stai attento in presenza di eccezioni. Gli array statici non presentano questi problemi.
Alexander Malakhov

31

static è una parola chiave in C e C ++, quindi piuttosto che un termine descrittivo generale, static ha un significato molto specifico quando applicato a una variabile o un array. Per aggravare la confusione, ha tre significati distinti all'interno di contesti separati. Per questo motivo, un array statico può essere fisso o dinamico.

Lasciatemi spiegare:

Il primo è specifico per C ++:

  • Un membro di una classe statica è un valore che non viene istanziato con il costruttore o eliminato con il distruttore. Ciò significa che il membro deve essere inizializzato e mantenuto in un altro modo. membro statico può essere puntatori inizializzati a null e quindi allocati la prima volta che viene chiamato un costruttore. (Sì, sarebbe statico e dinamico)

Due sono ereditati da C:

  • all'interno di una funzione, una variabile statica è quella la cui posizione di memoria è preservata tra le chiamate di funzione. È statico in quanto viene inizializzato solo una volta e mantiene il suo valore tra le chiamate di funzione (l'uso di statics rende una funzione non rientrante, ovvero non sicura per i thread)

  • le variabili statiche dichiarate al di fuori delle funzioni sono variabili globali a cui è possibile accedere solo dall'interno dello stesso modulo (file del codice sorgente con qualsiasi altro # include)

La domanda (credo) che volevi chiedere è quale sia la differenza tra array dinamici e array fissi o in fase di compilazione. Questa è una domanda più semplice, gli array in fase di compilazione vengono determinati in anticipo (quando il programma viene compilato) e fanno parte di uno stack frame di funzioni. Vengono allocati prima dell'esecuzione della funzione principale. gli array dinamici vengono allocati in fase di esecuzione con la parola chiave "new" (o la famiglia malloc da C) e la loro dimensione non è nota in anticipo. le allocazioni dinamiche non vengono eliminate automaticamente fino a quando il programma non viene interrotto.


4
+1, la tua risposta è la più precisa e precisa e avrebbe dovuto ricevere più voti.
Bosone Z

Se dichiari la dimensione dell'array con l' new[]operatore, com'è che la dimensione non è nota fino al runtime? ieint* p = new int[10]
wulfgarpro

"Vengono allocati prima dell'esecuzione della funzione principale." Perché allocare le variabili dello stack prima che venga inserito il blocco rilevante?
AlwaysLearning

Le variabili di stack (generalmente variabili locali in una funzione) hanno una dimensione e una posizione predefinite all'interno di uno stack frame e l'intero stack viene allocato prima che venga eseguita la funzione principale, @AlwaysLearning. Quando si entra in uno stack frame tramite la chiamata di funzione, il puntatore dello stack viene aggiornato, ma il nuovo stack frame è all'interno dello stack. Non viene mai allocato più stack. In effetti, un numero eccessivo di variabili (ad esempio un array gigante) o troppe chiamate di funzione aperte contemporaneamente provoca un overflow dello stack, per il quale questo sito prende il nome.
Joshua Clayton,

@JoshuaClayton Penso che questo non possa essere corretto. Come puoi allocare gli stack frame (notare il plurale) per una funzione ricorsiva quando non sai quante volte verrà inserito?
AlwaysLearning

11

Penso che la semantica usata nella tua classe sia fonte di confusione. Ciò che probabilmente si intende per "statico" è semplicemente "dimensione costante", e ciò che probabilmente si intende per "dinamico" è "dimensione variabile". In tal caso, un array di dimensioni costanti potrebbe essere simile a questo:

int x[10];

e uno "dinamico" sarebbe semplicemente qualsiasi tipo di struttura che consente di aumentare o diminuire lo spazio di archiviazione sottostante in fase di esecuzione. La maggior parte delle volte, std::vectorsarà sufficiente la classe della libreria standard C ++. Usalo in questo modo:

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

std::vectorè stato operator[]definito, quindi puoi usarlo con la stessa semantica di un array.


1
Penso che sia abbastanza chiaro che per "array dinamico" si intenda semplicemente un array allocato dinamicamente (ovvero, uno in cui la dimensione può essere specificata dinamicamente, in fase di esecuzione). Mi piacenew int[10]
jalf

@jalf: ero più preoccupato per il termine "statico". Preferisco chiamare un "array dinamico" un array di dimensioni variabili o allocate per motivi di coerenza.
Ben Collins

Un buon punto perché un array statico potrebbe essere automatico e implementato sullo stack o essere globale e implementato in una sezione dati. Entrambi sono statici ma internamente il codice che vi accede può essere molto diverso.
Bosone Z

9

Agli array statici viene allocata la memoria in fase di compilazione e la memoria viene allocata nello stack. Al contrario, agli array dinamici viene allocata memoria in fase di esecuzione e la memoria viene allocata dall'heap.

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

4
Un array globale è un array statico ed è implementato in una sezione dati e non dallo stack.
Bosone Z

8

È importante avere definizioni chiare del significato dei termini. Sfortunatamente sembrano esserci più definizioni del significato di array statici e dinamici.

Le variabili statiche sono variabili definite utilizzando l'allocazione della memoria statica . Questo è un concetto generale indipendente da C / C ++. In C / C ++ possiamo creare variabili statiche con scope globale, file o locale come questo:

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

Le variabili automatiche vengono solitamente implementate utilizzando l' allocazione della memoria basata sullo stack . Un array automatico può essere creato in C / C ++ in questo modo:

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

Ciò che questi array, x, y, ze whanno in comune è che la dimensione di ciascuno di essi è fissa ed è definita in fase di compilazione.

Uno dei motivi per cui è importante comprendere la distinzione tra un array automatico e un array statico è che l'archiviazione statica è solitamente implementata nella sezione dati (o sezione BSS ) di un file oggetto e il compilatore può utilizzare indirizzi assoluti per accedere agli array cosa impossibile con l'archiviazione basata su stack.

Ciò che di solito si intende per array dinamico non è ridimensionabile ma implementato utilizzando l'allocazione dinamica della memoria con una dimensione fissa determinata in fase di esecuzione. In C ++ questo viene fatto usando l' newoperatore .

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

Ma è possibile creare un array automatico con una dimensione delle correzioni definita in fase di esecuzione utilizzando alloca:

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

Per un vero array dinamico si dovrebbe usare qualcosa come std::vectorin C ++ (o un array a lunghezza variabile in C ).

Cosa si intendeva per l'assegnazione nella domanda del PO? Penso che sia chiaro che ciò che si desiderava non era un array statico o automatico ma uno che utilizzava l'allocazione dinamica della memoria utilizzando l' newoperatore o un array di dimensioni non fisse utilizzando ad es std::vector.


3

Penso che in questo contesto significhi che è statico nel senso che la dimensione è fissa. Usa std :: vector. Ha una funzione resize ().


2

Potresti avere un array pseudo dinamico in cui la dimensione è impostata dall'utente in fase di esecuzione, ma successivamente viene fissata.

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

Non fa parte del C ++ standard (in C99 e come estensione del compilatore per gcc).
crashmstr

1

Static Array :

  1. Gli array statici vengono allocati in memoria in fase di compilazione.
  2. La dimensione è fissa.
  3. Situato nello spazio di memoria dello stack.
  4. Per esempio. : int array [10]; // array di dimensione 10

Array dinamico:

  1. La memoria viene allocata in fase di esecuzione.
  2. La dimensione non è fissa.
  3. Situato nello spazio di memoria Heap.
  4. Per esempio. : int * array = nuovo int [10];

0

Sì, l'array statico viene creato in fase di compilazione, mentre l'array dinamico viene creato in fase di esecuzione. Quando la differenza per quanto riguarda le posizioni di memoria, le statiche si trovano sullo stack e le dinamiche vengono create sull'heap. Tutto ciò che viene posizionato sull'heap necessita della gestione della memoria fino a quando ea meno che non sia presente garbage collector come nel caso di .net framework altrimenti c'è il rischio di perdita di memoria.


0

Matrice statica: efficienza. Non è richiesta alcuna allocazione o deallocazione dinamica.

Gli array dichiarati in C, C ++ nella funzione incluso il modificatore statico sono statici. Esempio: static int foo [5];


1
@admdrew, è vero ma alla domanda non è mai stata data una buona risposta. La risposta migliore è la risposta di Joshua Clayton, ma penso che una risposta migliore sia questa stackoverflow.com/questions/17775066/…
Bosone Z

@Zboson Buono a sapersi, grazie. Eh e io ci siamo appena resi conto di aver fatto quel commento quasi un anno fa.
ammesso il

-3

statico arrary meens con dare su elementi a lato della matrice

meens arrary dinamici senza dare sugli elementi nel lato dell'array

esempio:

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

Penso che abbia detto corretto. Quando hai una lunghezza esatta per un array è un array statico e quando non dai la lunghezza è un array dinamico. ma siccome non sa scrivere in inglese, ecco perché la gente annota questa risposta.
muhammad tayyab
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.