J'étudie pour un examen final et je suis tombé sur une question curieuse qui faisait partie de l'examen de notre professeur a donné l'année dernière à certaines âmes pauvres. La question va faire quelque chose comme ceci:
est le programme suivant correct, ou pas? Si c'est le cas, écrivez ce que le programme génère. Si ce n'est pas le cas, écrivez pourquoi. P> blockquote>
Le programme: p>
xxx pré> Mon premier instinct était de répondre à "Le programme n'est pas correct, car
nouveau code> devrait être utilisé au lieu de
malloc code> ". Cependant, après avoir compilé le programme et le voyant de la sortie
23 code> Je me rends compte que cette réponse pourrait ne pas être correcte. P>
Le problème est que je m'attendais à
p2-> get_x ( ) code> Pour renvoyer un nombre arbitraire (tout ce qui est arrivé à être dans cet endroit de la mémoire lorsque
Malloc code> a été appelé). Cependant, il est retourné 0. Je ne suis pas sûr de savoir si c'est une coïncidence ou si les membres de la classe sont initialisés avec 0 quand il est
MALLOC CODE> -D. P>
- est ce problème (
p2--> x code> 0 après
malloc code>) la valeur par défaut? Devrais-je avoir
attendu fort> ceci? Li> - Que serait
votre forte> réponse à la question de mon professeur? (En plus d'oublier #include
code> pour malloc code>: p) li> ul> p>
5 Réponses :
Nouveau appelle le constructeur, Malloc ne le fera pas. Donc, votre objet sera dans un état inconnu. P>
Je sais malloc code> n'appelle pas le constructeur. Ma question concernait le membre de la classe
x code> - est-ce que cela est initialisé avec 0 ou obtient-il une valeur aléatoire qui était en mémoire à cet endroit?
@Felix: Si le constructeur n'est pas appelé, la valeur des données de membre est un comportement indéfini.
@Felix Initialisation X arrive dans le constructeur, il est donc indéfini. Même en utilisant nouveau code> ne serait pas zéro x Sauf si x n'était réellement réglé sur 0 dans le constructeur; Les champs membres ne reçoivent pas d'initialisations par défaut comme dans Java
Si vous construisez en mode de débogage, je crois que la mémoire sera probablement 0'd. Si vous êtes en mode de sortie, vous verrez probablement un nombre aléatoire dans cet espace.
@TLOCH - Cela dépend du compilateur. Microsoft C ++ remplira la mémoire non initialisée avec 0xCDCDCDCD (ou quelque chose comme ça. La mémoire libérée est également remplie de nombre similaire) en mode de débogage. En mode de sortie, il ne modifie pas du tout la mémoire lors de MALLOC / NOUVEAU.
@Tlohat, en fait, certains systèmes d'exploitation se passeront à zéro toute la mémoire allouée pour un processus (en libération). Cela n'accorde plus l'erreur que d'un programme de test simple (où MALLOC fournit toujours une nouvelle mémoire) peut sembler initialiser la mémoire, tandis que dans un environnement plus complexe, les valeurs sembleraient aléatoires.
Comme TLOCH mentionné, afin de repérer plus facilement les problèmes de débogage, certains compilateurs rechercheront la mémoire de Malloc afin que si vous trébuchez sur un 0, vous connaissez votre oublié de l'affecter. Malheureusement, utiliser 0 pourrait être exactement ce que vous avez voulu dans quel cas .. Vous allez supposer que cela fonctionne: /
@Tlohat: Comme Jmucchiello dit, le point ici est ... Un comportement non défini n'est pas défini.
Le comportement réel est inconnu, car Dans votre code, la deuxième partie est manquante, elle pourrait donc fonctionner dans un cas, mais vous ne pouvez pas dire exactement. P> nouveau code> agit assez identique à la même chose comme
malloc code> +
constructeur code> appel. p>
Non, p2-> x peut être quelque chose après l'appel à Malloc. Il se trouve que 0 dans votre environnement de test. P>
Qu'est-ce que tout le monde vous a dit, nouveau combine l'appel à obtenir la mémoire du Freestore avec un appel au constructeur de l'objet. MALLOC ne fait que la moitié de cela. P>
la fixant: tandis que le programme exemple est faux. Il n'est pas toujours faux d'utiliser "malloc" avec des cours. Il est parfaitement valable dans une situation de mémoire partagée que vous devez simplement ajouter un appel en place à nouveau: p>
Si vous utilisez un placement nouveau, vous devez également appeler explicitement le destructeur (vous ne pouvez pas utiliser Supprimer car vous n'avez pas utilisé de nouveau). De plus, vous devriez en-dire que ce n'est pas courant (Mainley utilisé lors de la construction de votre propre conteneur OBEJCTS lorsque vous pré-allouez le stockage pour plusieurs articles (pas seulement)))
Je discuterais d'utiliser Reterpret_cast Code>. Il souligne que vous faites quelque chose de très dangereux.
En réponse à Matthieu M., je n'aime pas modifier des questions de 5 ans, mais IMrecente, je réécrireais mon exemple final ci-dessus en tant que vide * p2buffer = malloc (Tailleof (CLS)); CLS * p2 = nouveau (p2buffer) CLS;. De cette façon, vous pouvez appeler plus tard P2-> ~ CLS et GRATUIT (P2Buffer); Et il est évident que P2 est l'objet "Classe" et P2Buffer est le pointeur de mémoire alloué.
Pourquoi 0 ne peut pas être un nombre arbitraire aussi? Êtes-vous en mode de débogage? Quel compilateur? p>
VC ++ Pré-remplit la mémoire nouvellement attribuée avec une chaîne de valeurs d'octets 0xcc (en mode de débogage de cours) afin que vous n'ayez pas obtenu de zéro pour une réponse si vous l'utilisiez. P>
MALLOC ne fait aucun garantie pour zéro de la mémoire qu'il a affectée et le résultat du programme est indéfini. P>
Sinon, il existe de nombreuses autres choses qui empêchent ce programme d'être correct C ++. COUT code> est dans NAMESPACE
STD code>,
MALLOC code> doit être compris via
#include
Pourquoi 0 ne peut-il pas être un nombre arbitraire aussi?
En dehors de quoi que ce soit d'autre code> devrait simplement être code>.
Vous pouvez également réparer les fuites de mémoire de votre professeur.
Les luttes de FMI Unibuc