Opérateur de nouveaux initialise la mémoire à zéro
Il y a un tel code:
#include <iostream>
int main(){
unsigned int* wsk2 = new unsigned int(5);
std::cout << "wsk2: " << wsk2 << " " << *wsk2 << std::endl;
delete wsk2;
wsk2 = new unsigned int;
std::cout << "wsk2: " << wsk2 << " " << *wsk2 << std::endl;
return 0;
}
Résultat:
wsk2: 0x928e008 5
wsk2: 0x928e008 0
J'ai lu que new
ne pas initialiser la mémoire avec des zéros. Mais ici, il semble qu'il n'. Comment ça fonctionne?
- Il n'est pas le cas, vous devez utiliser le nouveau unsigned int(). La lecture de variables non initialisées UB, un 0 est certainement possible.
- En aparté, dans la pratique, beaucoup de mémoire est nul de toute façon. Si vous faites une plaine malloc d'une grande partie de la mémoire, il est souvent tout à zéro sur certains systèmes, ou la plupart du zéro sur les autres.
- Pour la plupart des systèmes, cela n'est vrai que lorsque la mémoire est venu directement à partir de l'OS (pour des raisons de sécurité). Quand il est venu à partir de la mémoire cache par l'allocateur, il est probable qu'il contient tout ce qu'il a fait avant c'était gratuit()d. C'est aussi une raison pour laquelle de tels bugs, parfois, ne se pose pas dans le cas de tests/tests unitaires, mais seulement après un certain temps de la "vraie" programme en cours d'exécution. Valgrind à la rescousse ici.
- Oui. C'est le genre de mon point de vue. Si vous faites une nouvelle variable et de voir que c'est zéro, vous ne pouvez pas tout de suite supposer que quelque chose dans votre programme a mis à zéro. Depuis plus de mémoire est prêt à zéro, il est probablement non initialisée. Je pense que ma remarque est en fait plus proche pour répondre à la question que la plupart des réponses ci-dessous, parce que l'interlocuteur a voulu savoir pourquoi la mémoire non initialisée pourrait être de zéro.
- Essayez de l'allocation d'un tableau, le réglage de tous les éléments pour certaines valeur différente de zéro, puis de les supprimer[] et le répartir de nouveau - seul le premier élément sera remis à zéro - autres conservent leurs valeurs - qui je pense est un pecurliarity de l'allocateur de mémoire (testé sous Linux).
- Liées (demande pour les tableaux): stackoverflow.com/questions/2204176/...
Vous devez vous connecter pour publier un commentaire.
Il y a deux versions:
Fonctionne également pour les tableaux:
En réponse au commentaire ci-dessous.
Apparemment oui:
Résultats:
new/new[]
opérateurs? Vanew unsigned int[5]()
toujours de zéro-initialiser le tableau, même si il a un propriétaire, complètement sans rapport avec la mise en œuvre?operator new
est un utilisateur (développeur) la fonction définie, il peut faire ce qu'il aime. La norme ne permet pas de mettre des contraintes sur ce que cette fonction n'. Tout commeoperator==
pouvez faire tout ce que l'utilisateur définit (il n'a même pas besoin de retourner bool laisser seul test d'égalité (même si c'est mauvais si ce n'est pas)).()
syntaxe de la mémoire tampon sera initialisé à zéro sans aucun rapport avec le type de l'objet alloué et de son constructeur(s)? (Et je suppose que C++11 ne change rien à cet aspect)new unsigned int[5]()
zéros entiers?8.3.4 New
. Pourquoi elle a été modifiée. Parce que nous sommes en forçant la valeur d'initialisation. Voir11.6 Initializers
. Remarque on passe un pointeur vers le nouvel opérateur. La valeur dewsa
n'est PAS changé, c'est l'adresse qui est pointé qui est changé.new unsigned int
et pasnew unsigned int()
. (Je sais que la lecture de la suite de la deuxième ligne est UB, je demande juste, pourquoi cette réponse, qui n'explique pas la question, il a été accepté et upvoted au lieu de, par exemple, CBBailey réponse)default initialized (ie nothing happens)
) mais en plus, fournit des informations pertinentes et utiles à tous les programmeurs. Comment initialiser à zéro de la mémoire et comment il fonctionne avec les tableaux. Le point de la SORTE n'est pas juste pour répondre à la question posée, mais de fournir goo des informations supplémentaires.default initialized (ie nothing happens)
. Elle n'a évidemment répondu à l'OP question comme il l'a marqué la réponse avec une tique (donc il a résolu à sa question).default initialized (ie nothing happens)
et puis la deuxième variante qui vous permet de vous assurer que la mémoire est initialiséezero initialized (ie set to 0)
(ce qui est une chose utile à savoir qu'ils ne sais pas, mais j'ai fourni les renseignements, en plus).operator new
n'est pas garanti pour initialiser la mémoire pour rien, et le nouvelle expression qui alloue ununsigned int
sans nouvelle-initialiseur feuilles de l'objet avec une valeur indéterminée.La lecture de la valeur d'un objet non initialisé résultats dans comportement indéfini. Comportement indéfini comprend l'évaluation à la valeur zéro sans les mauvais effets, mais pourrait entraîner chose se passe afin que vous devriez éviter de cause.
En C++11, le langage utilisé est que les objets alloués sont par défaut-initialisé qui pour les non-types de classe signifie qu'aucune initialisation est effectuée. Ceci est différent de la signification de par défaut-initialisé en C++03.
Avec certains compilateurs, la version de débogage de nouveau va initialiser les données, mais il n'y a certainement rien de ce que vous pouvez compter sur.
Il est également possible que la mémoire juste eu 0 à partir d'une précédente utilisation. Ne présumez pas que rien de ce qui s'est passé à la mémoire entre les supprimer et de nouvelles. Il pourrait y avoir quelque chose dans l'arrière-plan que vous n'avez jamais remarqué. Aussi, la même valeur de pointeur peut ne pas être la même mémoire physique. Pages de mémoire se déplacé et paginées et dans. Un pointeur peut être mappé à un tout autre endroit que la précédente.
Bottom line: si vous n'avez pas spécifiquement l'initialisation d'un emplacement de mémoire, alors vous pouvez supposer rien sur son contenu. Le gestionnaire de mémoire peut même pas l'attribuer à une spécifiques emplacement de mémoire physique jusqu'à l'utilisation de la mémoire.
Moderne de gestion de la mémoire est étonnamment complexe, mais en tant que programmeur C++ vous n'avez pas vraiment (surtout‡). Les règles du jeu et vous n'aurez pas d'ennuis.
‡ Vous avez peut-être si vous êtes l'optimisation afin de réduire les défauts de page.
Ce n'est pas
operator new
, c'est lanew
de l'opérateur. Il y a effectivement une grande différence! La différence est queoperator new
est une fonction qui renvoie la mémoire brute; lorsque vous utilisez lenew
opérateur, il appelle un constructeur pour vous. C'est le constructeur qui est le réglage de la valeur de laint
, pasoperator new
.