2010-07-15 12 views
3

Possible en double:
Create new C++ object at specific memory address?Comment puis-je faire en sorte qu'un objet se construise à un emplacement particulier en mémoire?

Je suis en train d'écrire ce qui est essentiellement un pool d'objets allocateur, qui allouera une seule classe. J'alloue juste assez de mémoire pour correspondre aux objets dont j'ai besoin, et je passe des pointeurs vers des espaces à l'intérieur. Maintenant, ma question est la suivante: une fois que j'ai obtenu un pointeur dans mon pool, comment puis-je construire un objet là-bas?

Répondre

10

Vous utilisez l'emplacement nouveau. Comme ceci:

new(pointer) MyClass(); 
+1

Et rappelez-vous d'appeler la destructor avant désallouez la mémoire. –

+0

Génial, accepté. – Alex

0

Utilisez placement new

char memory[sizeof(Myclass)];  
void* place = memory;   

Myclass* f = new(place) Myclass(); 

Souvenez-vous

Vous êtes également seul responsable de destructing l'objet placé. Cela se fait par explicitement appeler la destructor:

f->~Myclass(); 

EDIT

Après avoir lu le commentaire de Martin York et section pertinente de la norme, il est tout à fait certain que vous ne devriez pas utiliser ce qui précède méthode (en utilisant des objets placés sur la pile avec le placement nouveau). Utilisez plutôt std::vector avec placement new comme Martin l'a suggéré.

+1

N'utilisez pas de variables de pile/globales avec un emplacement nouveau. La norme ne fournit aucune garantie sur l'alignement des variables de pile/globales. Par conséquent, vous devez utiliser la mémoire allouée dynamiquement (car la norme fournit des bénéficiaires sur son alignement). Donc, la façon la plus simple de le faire est pour nous un vecteur (car la partie données du vecteur est allouée dynamiquement). –

+0

@ Martin: Merci, je ne le savais pas. :) –

4

Utilisez l'emplacement nouveau.

std::vector<char> memory(sizeof(Myclass));  
void*    place = &memory[0];   

Myclass* f = new(place) Myclass(); 

Ne pas utiliser la méthode définie par la FAQ:

char  memory[sizeof(Myclass)]; // No alignment guarantees on this. 

Comme indiqué dans la FAQ, il est dangereux que la norme ne fournit pas l'alignement sur les bénéficiaires de cette mémoire. L'utilisation d'un vecteur standard vous donne des garanties quant à l'alignement car la section de données du vecteur est allouée dynamiquement et la norme fournit des garanties sur l'alignement de la mémoire allouée dynamiquement.

De: n2521 (la copie que j'ai sur mon bureau) Section: 3.7.3.1

Le pointeur retourné doit être convenablement aligné pour qu'il puisse être converti en un pointeur de tout type d'objet avec un l'exigence d'alignement fondamental (3.11), puis utilisée pour accéder à l'objet ou au tableau dans le stockage alloué (jusqu'à ce que le stockage soit explicitement libéré par un appel à une fonction de désallocation correspondante).

Qui nous pointe à 3.11

3.11 Alignement [basic.align]
5 Alignements ont un ordre de plus faible des alignements plus forts ou plus strictes. Les alignements plus stricts ont des valeurs d'alignement plus grandes. Une adresse qui satisfait une exigence d'alignement satisfait également toute exigence d'alignement valide plus faible.

Ne pas oublier d'appeler manuellement le destructor:

f->~Myclass()