Domanda

La memoria globale è inizializzata in C++?E se sì, come?

(Secondo) chiarimento:

Quando un programma si avvia, cosa c'è nello spazio di memoria che diventerà memoria globale, prima che le primitive vengano inizializzate?Sto cercando di capire se è azzerato, oppure spazzatura per esempio.

La situazione è:è possibile impostare un riferimento singleton - tramite an instance() chiamata, prima della sua inizializzazione:

MySingleton* MySingleton::_instance = NULL;

e ottenere come risultato due istanze singleton?

Vedi il mio quiz C++ su più istanze di un singleton...

È stato utile?

Soluzione

Sì, le primitive globali vengono inizializzate su NULL.

Esempio:

int x;

int main(int argc, char**argv)
{
  assert(x == 0);
  int y;
  //assert(y == 0); <-- wrong can't assume this.
}

Non è possibile fare alcuna ipotesi su classi, strutture, array, blocchi di memoria nell'heap...

È più sicuro inizializzare sempre tutto.

Altri suggerimenti

Dalla norma:

Gli oggetti con durata di archiviazione statica (3.7.1) devono essere inizializzati a zero (8.5) prima che abbia luogo qualsiasi altra inizializzazione.Vengono chiamate collettivamente l'inizializzazione zero e l'inizializzazione con un'espressione costante inizializzazione statica;tutte le altre inizializzazioni lo sono inizializzazione dinamica.Gli oggetti di tipo POD [plain old data] (3.9) con durata di archiviazione statica inizializzata con espressioni costanti (5.19) devono essere inizializzati prima che abbia luogo qualsiasi inizializzazione dinamica.Gli oggetti con durata di archiviazione statica definita nell'ambito del namespace nella stessa unità di traduzione e inizializzati dinamicamente devono essere inizializzati nell'ordine in cui la loro definizione appare nell'unità di traduzione.[Nota: 8.5.1 descrive l'ordine in cui i membri aggregati vengono inizializzati.L'inizialità di oggetti statici locali è descritta in 6.7.

Quindi sì, i globali che hanno una durata di archiviazione statica verranno inizializzati.Ovviamente i valori globali allocati, ad esempio, sull'heap non verranno inizializzati automaticamente.

Provenendo dal mondo embedded...

Il tuo codice viene compilato in tre tipi di memoria:
1..dati:memoria inizializzata
2..testo:costanti e codice
3..bss:memoria non inizializzata (inizializzata a 0 in C++ se non inizializzata esplicitamente)

I globali vanno in .data se inizializzati.In caso contrario vengono inseriti in .bss e azzerati nel codice premain.

Le variabili dichiarate con ambito statico/globale vengono sempre inizializzate almeno in VC++.

In alcune circostanze può effettivamente esserci una differenza di comportamento tra:

int x = 0;

int main() { ... }

E

int x;

int main() { ... }

Se stai utilizzando segmenti di dati condivisi, VC++ utilizza almeno la presenza di un'inizializzazione esplicita insieme a a #pragma data_seg per determinare se una particolare variabile deve andare nel segmento di dati condivisi o nel segmento di dati privati ​​per un processo.

Per ulteriore divertimento, considera cosa succede se hai un oggetto C++ statico con costruttore/distruttore dichiarato in un segmento di dati condiviso.Il costruttore/distruttore viene chiamato ogni volta che l'exe/dll si collega al segmento dati che quasi certamente non è quello che desideri.

Maggiori dettagli in questo Articolo della Knowledge Base

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top