1
votes

Pourquoi les deux pointeurs ont-ils la même adresse mémoire?

#include <iostream>

using namespace std;

int main()
{
    char* MainBlock = new char[100];

    char* SubBlock1 = new (MainBlock) char[20];

    char* SubBlock2 = new (MainBlock) char [20];

    cout  << static_cast<void*>(SubBlock1) << " " << static_cast<void*>(SubBlock2);


}
Why do both the pointers in the code above have the same address? I expected SubBlock2 to be 20 bytes after SubBlock 1.Does this mean I can allocate an endless number of pointers with placement new even though I only have 100 bytes?How can I ensure that SubBlock6 will be a nullptr or out of bounds using placement new?

5 commentaires

Parce que vous avez dit à C ++ de créer les objets à l'adresse MainBlock .


@tkausl Cela a du sens. Donc, je ne crée qu'un seul objet?


Techniquement, vous créez plusieurs objets. Ils vivent simplement à la même adresse (ce qui est un comportement indéfini si je me souviens bien).


@tkausl Cela semble bien défini; le tableau créé par le premier nouvel appel de placement est détruit en raison de la «réutilisation de son 'stockage» par le deuxième appel de nouvel emplacement. [basic.life] /1.4


@ user3702643 En plus des réponses ci-dessous, notez que vous ne devriez probablement jamais utiliser placement-new pour créer des tableaux. Voir Le placement nouveau pour les tableaux peut-il être utilisé dans un moyen portable?


3 Réponses :


1
votes

L'argument (MainBlock) est un argument placement . Vous dites en fait explicitement au programme d'allouer à la fois SubBlock1 et SubBlock2 à l'adresse de MainBlock .


0 commentaires

2
votes

Pourquoi les deux pointeurs du code ci-dessus ont-ils la même adresse?

Le nouveau placement accepte l'adresse exacte où il initialisera l'objet en cours de création. Vous passez la même adresse, vous obtenez la même adresse.

Cela signifie-t-il que je peux allouer un nombre infini de pointeurs avec un nouvel emplacement même si je n'ai que 100 octets?

Non. Chaque nouveau placement réutilise le stockage. Vous pouvez bien sûr réutiliser le stockage à l'infini, mais vous n'aurez toujours que les mêmes 100 caractères alloués au maximum.

Comment puis-je m'assurer que SubBlock6 sera un nullptr ou hors limites en utilisant le placement new?

Il n'y a aucun moyen. Le début est sur vous de fournir un stockage valide pour le placement nouveau pour créer les objets. Si vous ne le faites pas, le comportement n'est pas défini.

Et enfin, vous n'avez pas besoin de vous soucier du nouveau placement.

char *SubBlock1 = MainBlock;
char *SubBlock2 = MainBlock + 20;

Partitionne le tampon très bien. Assurez-vous simplement de supprimer [] uniquement la valeur du pointeur stockée dans MainBlock.


1 commentaires

Bon point sur delete [] . Pour cette raison, il est probablement logique de déclarer MainBlock comme char * const afin de ne pas le réaffecter accidentellement.



0
votes

Chaque nouvelle expression pour obtenir le l'adresse à laquelle construire l'objet appelle la fonction d'allocation appropriée. Une fois l'allocation terminée et l'adresse renvoyée par la fonction d'allocation, elle tente de construire l'objet exactement à l'adresse spécifiée.

Étant donné char * SubBlock1 = new (MainBlock) char [20]; , il appelle la fonction d'allocation suivante:

opérateur void * new [] (std :: size_t count, void * ptr);

Appelé par la nouvelle expression de placement de formulaire de tableau standard. L'implémentation standard de la bibliothèque n'effectue aucune action et renvoie ptr non modifié.

Comme le dit la documentation ci-dessus, l'appel de cette fonction d'allocation ne fait rien et renvoie l'adresse que vous avez passée sans modification. Ainsi, cette nouvelle expression construit 20 char exactement à MainBlock . C'est pourquoi vous obtenez la même adresse pour SubBlock1 et SubBlock2 .

Cela signifie-t-il que je peux allouer un nombre infini de pointeurs avec un nouvel emplacement même si je n'ai que 100 octets?

Non. Notez que allocation et construction sont deux choses différentes. Dans votre exemple, vous allouez la mémoire qu'une seule fois et y construisez des objets plusieurs fois. La disposition des objets construits sur la mémoire allouée dépend donc de vous.


0 commentaires