Question

La mémoire globale est-elle initialisée en C++ ?Et si oui, comment ?

(Deuxième) précision :

Au démarrage d'un programme, que trouve-t-on dans l'espace mémoire qui deviendra mémoire globale, avant l'initialisation des primitives ?J'essaie de comprendre s'il est mis à zéro, ou s'il s'agit d'un déchet par exemple.

La situation est la suivante :une référence singleton peut-elle être définie - via un instance() appeler, avant son initialisation :

MySingleton* MySingleton::_instance = NULL;

et obtenir deux instances singleton en conséquence ?

Voir mon quiz C++ sur plusieurs instances d'un singleton...

Était-ce utile?

La solution

Oui, les primitives globales sont initialisées à NULL.

Exemple:

int x;

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

Vous ne pouvez faire aucune hypothèse sur les classes, les structures, les tableaux, les blocs de mémoire sur le tas...

Il est plus sûr de toujours tout initialiser.

Autres conseils

De la norme :

Les objets avec une durée de stockage statique (3.7.1) doivent être initialisés à zéro (8.5) avant toute autre initialisation.L'initialisation zéro et l'initialisation avec une expression constante sont collectivement appelées initialisation statique;toutes les autres initialisations sont initialisation dynamique.Les objets de types POD [plain old data] (3.9) avec une durée de stockage statique initialisée avec des expressions constantes (5.19) doivent être initialisés avant toute initialisation dynamique.Les objets dont la durée de stockage statique est définie dans la portée de l'espace de noms dans la même unité de traduction et initialisés dynamiquement doivent être initialisés dans l'ordre dans lequel leur définition apparaît dans l'unité de traduction.[Remarque : 8.5.1 décrit l'ordre dans lequel les membres de l'agrégat sont initialisés.L'initiation des objets statiques locaux est décrit dans 6.7.

Alors oui, les globales qui ont une durée de stockage statique seront initialisées.Les globaux alloués, par exemple, sur le tas ne seront bien sûr pas initialisés automatiquement.

Venant du monde embarqué...

Votre code est compilé dans trois types de mémoire :
1..données:mémoire initialisée
2..texte:constantes et code
3..bss :mémoire non initialisée (initialisée à 0 en C++ si elle n'est pas explicitement initialisée)

Les globaux vont dans .data s'ils sont initialisés.Sinon, ils sont placés dans .bss et mis à zéro dans le code prémain.

Les variables déclarées avec une portée statique/globale sont toujours initialisées sous VC++ au moins.

Dans certaines circonstances, il peut effectivement y avoir une différence de comportement entre :

int x = 0;

int main() { ... }

et

int x;

int main() { ... }

Si vous utilisez des segments de données partagés, VC++ utilise au moins la présence d'une initialisation explicite ainsi qu'un #pragma data_seg pour déterminer si une variable particulière doit aller dans le segment de données partagées ou dans le segment de données privées pour un processus.

Pour plus de plaisir, réfléchissez à ce qui se passe si vous avez un objet C++ statique avec un constructeur/destructeur déclaré dans un segment de données partagé.Le constructeur/destructeur est appelé chaque fois que l'exe/dll s'attache au segment de données, ce qui n'est certainement pas ce que vous voulez.

Plus de détails dans ceci Article de la base de connaissances

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top