 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
nico Guest
|
Posted: Thu Jun 23, 2005 3:27 pm Post subject: Comment delete connait-il la taille du block à désallouer ? |
|
|
Bonjour,
Comment "delete" connait-il la taille du block à désallouer ?
(question dans le cadre d'une surcharge de l'opérateur delete)
void operator delete(void * obj)
{
//ici sizeof(obj) renvoie une taille incorrecte
// dans le cadre d'héritage...
}
Merci.
--
nico
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
|
| Back to top |
|
 |
nico Guest
|
Posted: Thu Jun 23, 2005 3:39 pm Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
nico wrote:
| Quote: | Bonjour,
Comment "delete" connait-il la taille du block à désallouer ?
(question dans le cadre d'une surcharge de l'opérateur delete)
void operator delete(void * obj)
{
//ici sizeof(obj) renvoie une taille incorrecte
// dans le cadre d'héritage...
}
Merci.
|
oups je pensais sizeof(*obj) mais ca ne marche pas evidemment
--
nico
|
|
| Back to top |
|
 |
nico Guest
|
Posted: Thu Jun 23, 2005 3:39 pm Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
Jean-Marc Bourguet wrote:
| Quote: | nico <nospam (AT) spam (DOT) fr> writes:
Comment "delete" connait-il la taille du block à désallouer ?
Il doit le deduire de l'adresse passee.
A+
|
Comment ?
--
nico
|
|
| Back to top |
|
 |
nico Guest
|
Posted: Thu Jun 23, 2005 3:42 pm Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
nico wrote:
| Quote: | Bonjour,
Comment "delete" connait-il la taille du block à désallouer ?
(question dans le cadre d'une surcharge de l'opérateur delete)
void operator delete(void * obj)
{
//ici sizeof(obj) renvoie une taille incorrecte
// dans le cadre d'héritage...
}
Merci.
|
une technique pas élégante mais qui marche :
#define delete(x) __delete(x)
template<class T> void __delete(T* obj)
{
//sizeof(T) fonctionne correctemet
}
--
nico
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Thu Jun 23, 2005 3:45 pm Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
nico wrote:
| Quote: | Comment "delete" connait-il la taille du block à désallouer ?
(question dans le cadre d'une surcharge de l'opérateur delete)
void operator delete(void * obj)
{
//ici sizeof(obj) renvoie une taille incorrecte
// dans le cadre d'héritage...
|
Même sans l'héritage:-). La taille d'un void* ne change pas
beaucoup.
C'est le problème de l'implementation ; si elle a besoin de la
taille, il faut qu'elle puisse le retrouver à partir de
l'adresse.
Typiquement, l'implémentation va utiliser un en-tête au bloc,
avec toutes les informations dont elle a besoin. Au retour de
new, elle va faire « return p + quelqueChose », et la première
chose qu'elle va faire en delete, c'est « p = obj -
quelqueChose », pour pouvoir accéder à l'en-tête.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
Posted: Thu Jun 23, 2005 3:55 pm Post subject: Re: Comment delete connait-il la taille du blockà désallouer |
|
|
nico <nospam (AT) spam (DOT) fr> writes:
| Quote: | Jean-Marc Bourguet wrote:
nico <nospam (AT) spam (DOT) fr> writes:
Comment "delete" connait-il la taille du block à désallouer ?
Il doit le deduire de l'adresse passee.
Comment ?
|
C'est son probleme. Plusieurs techniques sont utilisees. Les deux
qui me viennent a l'esprit: stocker la taille avant et la deduire de
l'adresse (parce que l'adresse fait partie d'une zone utilisee pour
fournir des blocs de taille fixe).
Ceci par exemple est conforme:
void * rawptr = ::operator new(sizeof(A) + 20);
A* ptr = new(rawptr) A;
ptr->~A();
::operator delete(rawptr);
donc tu ne peux pas utiliser des informations de type.
D'ailleurs je me demande si
void * rawptr = ::operator new(sizeof(A) + 20);
A* ptr = new(rawptr) A;
ptr->~A();
delete rawptr;
ou
assert(sizeof(A) > sizeof(B));
A* ptr = new A;
ptr->~A();
B* ptrB = new(ptr) B
delete ptrB;
ou encore
void * rawptr = ::operator new(sizeof(A) + 20);
A* ptr = new(rawptr) A;
delete ptr;
ne le sont pas aussi.
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
|
|
| Back to top |
|
 |
nico Guest
|
Posted: Thu Jun 23, 2005 4:22 pm Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
Salut,
| Quote: | Typiquement, l'implémentation va utiliser un en-tête au bloc,
avec toutes les informations dont elle a besoin. Au retour de
new, elle va faire « return p + quelqueChose », et la première
chose qu'elle va faire en delete, c'est « p = obj -
quelqueChose », pour pouvoir accéder à l'en-tête.
|
En fait actuellement j'utilise un systeme très simple :
char * block;
char * block_info;
block contient les données et block_info les données d'allocation, si bien
que si block_info[X]==0 alors block[X] est utilisable sinon block[X] est
utilisé.
Ce système a comme inconvénient majeur d'utiliser deux fois plus de mémoire
qu'il ne faudrait. (j'ai pensé stocker 8 infos par char (1 par bit) mais je
l'ai pas encore implementé)
Ensuite, à cause de ce problème de sizeof, je voulais changer pour un
système comme celui là :
typedef struct block_info
{
uint address; //adresse du block
size_t size; //longueur
} block_info;
char * data;
block_info * infos;
mais la idem, si on alloue bcp de petits blocks ce n'est pas rentable (on
gache trop de mémoire).
Je n'avais pas pensé, par contre, à un système d'entête comme tu le
suggères, j'avoue que ca serait une bonne idée car on a plus à stocker
l'adresse, et donc, si j'ai bien compris ce que tu as voulu dire, un block
aurait cette tete :
[[taille sur un int][data]]
Je vais essayer comme ca (sauf si vous avez encore mieux ).
--
nico
|
|
| Back to top |
|
 |
nico Guest
|
Posted: Thu Jun 23, 2005 4:24 pm Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
Erratum :
| Quote: | [[taille sur un int][data]]
sur un unsigned int (ou size_t qui doit revenir au même). |
--
nico
|
|
| Back to top |
|
 |
Patrick 'Zener' Brunet Guest
|
Posted: Thu Jun 23, 2005 5:53 pm Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
Bonjour.
Je réponds à nico <nospam (AT) spam (DOT) fr> qui a écrit :
| Quote: | Bonjour,
Comment "delete" connait-il la taille du block à désallouer ?
(question dans le cadre d'une surcharge de l'opérateur delete)
void operator delete(void * obj)
{
//ici sizeof(obj) renvoie une taille incorrecte
// dans le cadre d'héritage...
}
|
Il y a deux manières de l'envisager :
- soit le compilo maintient une base de données des adresses&tailles de
blocs, et génère lui-même lors de la libération l'information dont le
programmeur peut ainsi se dispenser,
- soit le mécanisme d'allocation maintient un header en tête de chaque bloc,
et il est assez facile dans un principe d'implémentation de se rendre compte
que cet entête :
- - ne peut se situer qu'au début du bloc (puisqu'à la libération sa taille
est encore inconnue),
- - doit exister pour les blocs libres et alloués (tant que des libres non
consécutifs ne peuvent pas être fusionnés : défragmentation),
- - doit contenir au moins (mais ça suffit formellement) ce statut du bloc +
sa taille complète (entête compris).
Donc typiquement l'allocation se fait sous la forme d'un bloc [taille
demandée + taille entête + déchet sacrifié], mais ensuite le mécanisme
d'allocation restitue un pointeur décalé à la fin de l'entête, lequel entête
restera donc "en dessous" des données de l'utilisateur. A la libération, le
décalage inverse permet de retrouver le début du bloc au sens "machine". Si
le bloc est libéré mais ne peut pas être fusionné car il est entouré de
blocs toujours alloués, alors l'ex-espace utilisateur est réutilisé pour y
loger des pointeurs de chaînage des blocs libres, en attendant donc la
libération d'un bloc contigu.
Il est possible aussi, en mode debug, de rajouter dans le déchet et dans
l'entête des marqueurs "sentinelles" dont l'intégrité est vérifiée à la
libération.
Il y a aussi un point important à ne pas négliger : l'allocation est
supposée fournir des pointeurs correctement alignés pour tout usage, ce qui
veut implique que la taille de l'entête doit être arrondie selon la règle
d'alignement la plus contraignante, ou bien pour éviter ce déchet-là, que le
mécanisme d'allocation travaille avec des pointeurs de blocs qui ne
respectent pas forcément cette règle. En tout cas l'utilisateur ne doit rien
voir de tout ça.
En C++, an niveau de l'opérateur new[], c'est encore plus compliqué parce
que le bloc retourné doit idéalement contenir un second entête pour
mémoriser le cardinal du tableau d'objets, afin qu'une implémentation de
delete[] (si on s'y risque) puisse s'y retrouver aussi.
Bref c'est assez sympa, il faut avoir implémenté ça une fois dans sa vie
pour avoir ensuite une juste idée des conséquences de ses choix
"d'utilisateur" sur le taux de moulinage.
Ca donne aussi une autre vision des performances à attendre de ces langages
prétendument merveilleux où l'on n'a plus à se préoccuper des pointeurs ;-)
Hope It Helps,
Cordialement,
--
/***************************************
* Patrick BRUNET
* E-mail: lien sur http://zener131.free.fr/ContactMe
***************************************/
|
|
| Back to top |
|
 |
nico Guest
|
Posted: Thu Jun 23, 2005 6:10 pm Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
Salut,
| Quote: | Il y a deux manières de l'envisager :
snip
Hope It Helps,
|
Merci pour ta réponse, c'est très interessant.
Je suis aussi d'accord sur le fait qu'il fau avoir implémenté ca ua moins
une fois dans sa vie C'est pour ca que je le fais :)
--
nico
|
|
| Back to top |
|
 |
adebaene@club-internet.fr Guest
|
Posted: Fri Jun 24, 2005 7:42 am Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
nico a écrit :
| Quote: | Bonjour,
Comment "delete" connait-il la taille du block à désallouer ?
(question dans le cadre d'une surcharge de l'opérateur delete)
|
Tout le monde t'a déjà répondu sur les différentes méthodes
envisageables, mais si c'est pour surcharger l'opérateur delete, tu
n'as pas à t'en soucier : Tu as le droit de fournir une des 2 versions
suivantes de l'operateur delete :
- void operator delete (void* p);
- void operator delete(void* p, std::size_t size);
Si tu fournis la 2ème version, c'est à l'implémentation de te
fournir la taille correcte de la zone pointée.
Arnaud
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Fri Jun 24, 2005 10:54 am Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
nico wrote:
| Quote: | Je n'avais pas pensé, par contre, à un système d'entête comme
tu le suggères,
|
C'est quand même quasi universel. La norme permet tout, mais
dans la pratique, je ne connais pas d'implémentation qui ne se
sert pas des données cachées devant l'adresse renvoyée par
malloc.
| Quote: | j'avoue que ca serait une bonne idée car on a plus à stocker
l'adresse, et donc, si j'ai bien compris ce que tu as voulu
dire, un block aurait cette tete :
[[taille sur un int][data]]
Je vais essayer comme ca (sauf si vous avez encore mieux ).
|
Il faut faire gaffe aux contraints de l'alignement, quand même.
Sur les systèmes que j'utilise, au moins, la taille d'un int,
c'est 4, mais les doubles ont besoin d'un alignement de 8.
Sinon, c'est une solution éprouée.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Fri Jun 24, 2005 10:58 am Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
[email]adebaene (AT) club-internet (DOT) fr[/email] wrote:
| Quote: | nico a écrit :
Comment "delete" connait-il la taille du block à désallouer
? (question dans le cadre d'une surcharge de l'opérateur
delete)
Tout le monde t'a déjà répondu sur les différentes méthodes
envisageables, mais si c'est pour surcharger l'opérateur
delete, tu n'as pas à t'en soucier : Tu as le droit de fournir
une des 2 versions suivantes de l'operateur delete :
- void operator delete (void* p);
- void operator delete(void* p, std::size_t size);
Si tu fournis la 2ème version, c'est à l'implémentation de te
fournir la taille correcte de la zone pointée.
|
D'où est-ce que tu tires ça ? Parce qu'il n'y en a pas mention
dans la section §18.4 de la norme. Est-ce que tu ne serais pas
en train de confondre avec les operator delete membre (où c'est
bien le cas) ?
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
|
|
| Back to top |
|
 |
Laurent Deniau Guest
|
Posted: Fri Jun 24, 2005 12:38 pm Post subject: Re: Comment delete connait-il la taille du block à désalloue |
|
|
[email]kanze (AT) gabi-soft (DOT) fr[/email] wrote:
| Quote: | nico wrote:
Comment "delete" connait-il la taille du block à désallouer ?
(question dans le cadre d'une surcharge de l'opérateur delete)
void operator delete(void * obj)
{
//ici sizeof(obj) renvoie une taille incorrecte
// dans le cadre d'héritage...
Même sans l'héritage:-). La taille d'un void* ne change pas
beaucoup.
}
C'est le problème de l'implementation ; si elle a besoin de la
taille, il faut qu'elle puisse le retrouver à partir de
l'adresse.
Typiquement, l'implémentation va utiliser un en-tête au bloc,
avec toutes les informations dont elle a besoin. Au retour de
new, elle va faire « return p + quelqueChose », et la première
chose qu'elle va faire en delete, c'est « p = obj -
quelqueChose », pour pouvoir accéder à l'en-tête.
|
Cette approche est quelque peu ancienne et sous-optimale en place
memoire. Il y a de nombreuses alternatives bien plus efficace ou la
taille est centralisee par arena/pool/allocator.
a+, ld.
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|