9
votes

Qu'advient-il des membres de la classe lorsque MALLOC est utilisé au lieu de nouveau?

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.

Le programme: xxx

Mon premier instinct était de répondre à "Le programme n'est pas correct, car nouveau devrait être utilisé au lieu de malloc ". Cependant, après avoir compilé le programme et le voyant de la sortie 23 Je me rends compte que cette réponse pourrait ne pas être correcte.

Le problème est que je m'attendais à p2-> get_x ( ) Pour renvoyer un nombre arbitraire (tout ce qui est arrivé à être dans cet endroit de la mémoire lorsque Malloc 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 -D.

  • est ce problème ( p2--> x 0 après malloc ) la valeur par défaut? Devrais-je avoir attendu ceci?
  • Que serait votre réponse à la question de mon professeur? (En plus d'oublier #include pour malloc : p)

4 commentaires

Pourquoi 0 ne peut-il pas être un nombre arbitraire aussi?


En dehors de quoi que ce soit d'autre devrait simplement être .


Vous pouvez également réparer les fuites de mémoire de votre professeur.


Les luttes de FMI Unibuc


5 Réponses :


4
votes

Nouveau appelle le constructeur, Malloc ne le fera pas. Donc, votre objet sera dans un état inconnu.


8 commentaires

Je sais malloc n'appelle pas le constructeur. Ma question concernait le membre de la classe x - 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 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.



1
votes

Le comportement réel est inconnu, car nouveau agit assez identique à la même chose comme malloc + constructeur appel.

Dans votre code, la deuxième partie est manquante, elle pourrait donc fonctionner dans un cas, mais vous ne pouvez pas dire exactement.


0 commentaires

16
votes
  • est ce comportement (p2-> x étant 0 après malloc) la valeur par défaut? Devrais-je m'attendre à ce sujet?

    Non, p2-> x peut être quelque chose après l'appel à Malloc. Il se trouve que 0 dans votre environnement de test.

    • Quelle serait votre réponse à la question de mon professeur? (En plus d'oublier de #include pour Malloc: 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.

      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: xxx


3 commentaires

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 . 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é.



0
votes

Pourquoi 0 ne peut pas être un nombre arbitraire aussi? Êtes-vous en mode de débogage? Quel compilateur?

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.


0 commentaires

0
votes

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.

Sinon, il existe de nombreuses autres choses qui empêchent ce programme d'être correct C ++. COUT est dans NAMESPACE STD , MALLOC doit être compris via #include et iostream.h isn ' t conformité standard.


0 commentaires