J'ai besoin de savoir si une classe est cree sur la pile ou sur le
tas.
J'ai definit un booleen qui porte cette indication, et qui est
renseign=E9 au moment de la creation par une focntoin new priv=E9e
bool CBase1::operator=3D=3D(const CBase1& autre)
{
// test d'=E9galit=E9 sur les noms pas sur la facon dont la ressource a
=E9t=E9 cr=E9=E9e
return ( autre.m_name =3D=3D m_name );
}
void CBase1::Copy( const CBase1& autre)
{
if( &autre !=3D this )
{
// ne pas copier cree_dyn !
m_name =3D autre.m_name;
}
}
Ca marche plutot bien en apparence, et je me sert de cette classe
comme base pour le polymorphisme.
Par contre j'ai une interrogation, y a t il une autre facon de faire?
J'ai utilis=E9 malloc et free, car la fonction globale new appelle une
2eme fois le constructeur ce qui est genant.
J'ai besoin de savoir si une classe est cree sur la pile ou sur le tas.
Juste par curiosité, pourquoi donc as-tu besoin de le savoir ?
James Kanze
On Mar 24, 2:26 am, wrote:
J'ai besoin de savoir si une classe est cree sur la pile ou sur le tas.
C'est impossible de façon portable. Sur beaucoup de systèmes, en revanche, la pile se trouve à des adresses connues, et la comparaison d'adresse marche : une solution fréquente sur Sparc ou sur PC, c'est de mettre la pile tout en haut de l'espace adresse ; puisque la pile croît vers le bas sur ces deux processeurs, si l'adresse est supérieur à l'adresse d'une variable locale, elle est sur la pile.
Traditionnellement aussi les Unix définissait un symbole « end », à la fin de la mémoire statique. Donc, sur un PC (au moins sous Linux) ou sur un Sparc :
char const* located( void* p ) { extern int end ; if ( p > &p ) { return "local" ; } else if ( p < &end ) { return "static" ; } else { return "dynamic" ; } }
(En revanche, je sais que ça ne marche pas du tout sur les PA de HP.)
Aussi, évidemment, ça ne marche que dans le cas des programmes mono-thread. Dans un environement multi-thread, chaque processus a sa propre pile, typiquement allouée sur le tas.
J'ai definit un booleen qui porte cette indication, et qui est renseigné au moment de la creation par une focntoin new privée
C'est la solution classique. Ça ne permet toujours pas de distinguer entre les variables locales et les statiques, ce n'est pas thread-safe, et ça ne marche pas si les objets se trouvent dans un tableau (c-à-d alloués avec new[]).
[...]
Ca marche plutot bien en apparence, et je me sert de cette classe comme base pour le polymorphisme.
C'est que tu n'en as pas essayé les cas que j'ai énumérés ci-dessus.
Par contre j'ai une interrogation, y a t il une autre facon de faire? J'ai utilisé malloc et free, car la fonction globale new appelle une 2eme fois le constructeur ce qui est genant.
La fonction new n'appelle de constructeur. C'est une expression new qui l'appelle. Donc :
p = new Toto ; // appel du constructeur... p = operator new( sizeof Toto ) ; // pas d'appel du constructeur...
La même dichotomie existe entre la fonction delete, et une experssion delete.
-- James Kanze (Gabi Software) email: 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
On Mar 24, 2:26 am, d...@hotmail.com wrote:
J'ai besoin de savoir si une classe est cree sur la pile ou
sur le tas.
C'est impossible de façon portable. Sur beaucoup de systèmes, en
revanche, la pile se trouve à des adresses connues, et la
comparaison d'adresse marche : une solution fréquente sur Sparc
ou sur PC, c'est de mettre la pile tout en haut de l'espace
adresse ; puisque la pile croît vers le bas sur ces deux
processeurs, si l'adresse est supérieur à l'adresse d'une
variable locale, elle est sur la pile.
Traditionnellement aussi les Unix définissait un symbole
« end », à la fin de la mémoire statique. Donc, sur un PC (au
moins sous Linux) ou sur un Sparc :
char const*
located(
void* p )
{
extern int end ;
if ( p > &p ) {
return "local" ;
} else if ( p < &end ) {
return "static" ;
} else {
return "dynamic" ;
}
}
(En revanche, je sais que ça ne marche pas du tout sur les PA de
HP.)
Aussi, évidemment, ça ne marche que dans le cas des programmes
mono-thread. Dans un environement multi-thread, chaque processus
a sa propre pile, typiquement allouée sur le tas.
J'ai definit un booleen qui porte cette
indication, et qui est renseigné au moment de la creation par
une focntoin new privée
C'est la solution classique. Ça ne permet toujours pas de
distinguer entre les variables locales et les statiques, ce
n'est pas thread-safe, et ça ne marche pas si les objets se
trouvent dans un tableau (c-à-d alloués avec new[]).
[...]
Ca marche plutot bien en apparence, et je me sert de cette classe
comme base pour le polymorphisme.
C'est que tu n'en as pas essayé les cas que j'ai énumérés
ci-dessus.
Par contre j'ai une interrogation, y a t il une autre facon de faire?
J'ai utilisé malloc et free, car la fonction globale new appelle une
2eme fois le constructeur ce qui est genant.
La fonction new n'appelle de constructeur. C'est une expression
new qui l'appelle. Donc :
p = new Toto ; // appel du constructeur...
p = operator new( sizeof Toto ) ;
// pas d'appel du constructeur...
La même dichotomie existe entre la fonction delete, et une
experssion delete.
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
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
J'ai besoin de savoir si une classe est cree sur la pile ou sur le tas.
C'est impossible de façon portable. Sur beaucoup de systèmes, en revanche, la pile se trouve à des adresses connues, et la comparaison d'adresse marche : une solution fréquente sur Sparc ou sur PC, c'est de mettre la pile tout en haut de l'espace adresse ; puisque la pile croît vers le bas sur ces deux processeurs, si l'adresse est supérieur à l'adresse d'une variable locale, elle est sur la pile.
Traditionnellement aussi les Unix définissait un symbole « end », à la fin de la mémoire statique. Donc, sur un PC (au moins sous Linux) ou sur un Sparc :
char const* located( void* p ) { extern int end ; if ( p > &p ) { return "local" ; } else if ( p < &end ) { return "static" ; } else { return "dynamic" ; } }
(En revanche, je sais que ça ne marche pas du tout sur les PA de HP.)
Aussi, évidemment, ça ne marche que dans le cas des programmes mono-thread. Dans un environement multi-thread, chaque processus a sa propre pile, typiquement allouée sur le tas.
J'ai definit un booleen qui porte cette indication, et qui est renseigné au moment de la creation par une focntoin new privée
C'est la solution classique. Ça ne permet toujours pas de distinguer entre les variables locales et les statiques, ce n'est pas thread-safe, et ça ne marche pas si les objets se trouvent dans un tableau (c-à-d alloués avec new[]).
[...]
Ca marche plutot bien en apparence, et je me sert de cette classe comme base pour le polymorphisme.
C'est que tu n'en as pas essayé les cas que j'ai énumérés ci-dessus.
Par contre j'ai une interrogation, y a t il une autre facon de faire? J'ai utilisé malloc et free, car la fonction globale new appelle une 2eme fois le constructeur ce qui est genant.
La fonction new n'appelle de constructeur. C'est une expression new qui l'appelle. Donc :
p = new Toto ; // appel du constructeur... p = operator new( sizeof Toto ) ; // pas d'appel du constructeur...
La même dichotomie existe entre la fonction delete, et une experssion delete.
-- James Kanze (Gabi Software) email: 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
dug8C
On 24 mar, 02:32, Fabien LE LEZ wrote:
On 23 Mar 2007 18:26:54 -0700, :
J'ai besoin de savoir si une classe est cree sur la pile ou sur le tas.
Juste par curiosité, pourquoi donc as-tu besoin de le savoir ?
En fait j'ai crée une classe qui manipule la classe CBase1 et qui gère la libération de la mémoire. J'ai besoin de savoir si je dois appeller delete si CBase1 est créée sur le tas.
On 24 mar, 02:32, Fabien LE LEZ <grams...@gramster.com> wrote:
On 23 Mar 2007 18:26:54 -0700, d...@hotmail.com:
J'ai besoin de savoir si une classe est cree sur la pile ou sur le
tas.
Juste par curiosité, pourquoi donc as-tu besoin de le savoir ?
En fait j'ai crée une classe qui manipule la classe CBase1 et qui gère
la libération de la mémoire.
J'ai besoin de savoir si je dois appeller delete si CBase1 est créée
sur le tas.
J'ai besoin de savoir si une classe est cree sur la pile ou sur le tas.
Juste par curiosité, pourquoi donc as-tu besoin de le savoir ?
En fait j'ai crée une classe qui manipule la classe CBase1 et qui gère la libération de la mémoire. J'ai besoin de savoir si je dois appeller delete si CBase1 est créée sur le tas.
Fabien LE LEZ
On 24 Mar 2007 02:54:51 -0700, :
J'ai besoin de savoir si je dois appeller delete si CBase1 est créée sur le tas.
Utilise un GC, et comme ça tu n'auras jamais besoin d'appeler delete.
On 24 Mar 2007 02:54:51 -0700, dug8C@hotmail.com:
J'ai besoin de savoir si je dois appeller delete si CBase1 est créée
sur le tas.
Utilise un GC, et comme ça tu n'auras jamais besoin d'appeler delete.
J'ai besoin de savoir si je dois appeller delete si CBase1 est créée sur le tas.
Utilise un GC, et comme ça tu n'auras jamais besoin d'appeler delete.
dug8C
On 24 mar, 09:35, "James Kanze" wrote:
On Mar 24, 2:26 am, wrote:
J'ai besoin de savoir si une classe est cree sur la pile ou sur le tas.
C'est impossible de façon portable. Sur beaucoup de systèmes, en revanche, la pile se trouve à des adresses connues, et la comparaison d'adresse marche : une solution fréquente sur Sparc ou sur PC, c'est de mettre la pile tout en haut de l'espace adresse ; puisque la pile croît vers le bas sur ces deux processeurs, si l'adresse est supérieur à l'adresse d'une variable locale, elle est sur la pile.
Merci pour ces explications, mais comment fait-on pour mettre la pile en haut de l'espace adresse ? Je ne pensais pas qu'on pouvait le modifier
[...]
Ca marche plutot bien en apparence, et je me sert de cette classe comme base pour le polymorphisme.
C'est que tu n'en as pas essayé les cas que j'ai énumérés ci-dessus.
Effectivement je n'ai pas essayé les creations avec new[] , ni en multi-thread Dans ces cas là, existe -il une solution ?
Par contre j'ai une interrogation, y a t il une autre facon de faire? J'ai utilisé malloc et free, car la fonction globale new appelle une 2eme fois le constructeur ce qui est genant.
La fonction new n'appelle de constructeur. C'est une expression new qui l'appelle. Donc :
p = new Toto ; // appel du constructeur... p = operator new( sizeof Toto ) ; // pas d'appel du constructeur...
La même dichotomie existe entre la fonction delete, et une experssion delete.
Ok, je vois que j'utilisais mal la fonction new.
On 24 mar, 09:35, "James Kanze" <james.ka...@gmail.com> wrote:
On Mar 24, 2:26 am, d...@hotmail.com wrote:
J'ai besoin de savoir si une classe est cree sur la pile ou
sur le tas.
C'est impossible de façon portable. Sur beaucoup de systèmes, en
revanche, la pile se trouve à des adresses connues, et la
comparaison d'adresse marche : une solution fréquente sur Sparc
ou sur PC, c'est de mettre la pile tout en haut de l'espace
adresse ; puisque la pile croît vers le bas sur ces deux
processeurs, si l'adresse est supérieur à l'adresse d'une
variable locale, elle est sur la pile.
Merci pour ces explications, mais comment fait-on pour mettre la pile
en haut de l'espace adresse ?
Je ne pensais pas qu'on pouvait le modifier
[...]
Ca marche plutot bien en apparence, et je me sert de cette classe
comme base pour le polymorphisme.
C'est que tu n'en as pas essayé les cas que j'ai énumérés
ci-dessus.
Effectivement je n'ai pas essayé les creations avec new[] , ni en
multi-thread
Dans ces cas là, existe -il une solution ?
Par contre j'ai une interrogation, y a t il une autre facon de faire?
J'ai utilisé malloc et free, car la fonction globale new appelle une
2eme fois le constructeur ce qui est genant.
La fonction new n'appelle de constructeur. C'est une expression
new qui l'appelle. Donc :
p = new Toto ; // appel du constructeur...
p = operator new( sizeof Toto ) ;
// pas d'appel du constructeur...
La même dichotomie existe entre la fonction delete, et une
experssion delete.
J'ai besoin de savoir si une classe est cree sur la pile ou sur le tas.
C'est impossible de façon portable. Sur beaucoup de systèmes, en revanche, la pile se trouve à des adresses connues, et la comparaison d'adresse marche : une solution fréquente sur Sparc ou sur PC, c'est de mettre la pile tout en haut de l'espace adresse ; puisque la pile croît vers le bas sur ces deux processeurs, si l'adresse est supérieur à l'adresse d'une variable locale, elle est sur la pile.
Merci pour ces explications, mais comment fait-on pour mettre la pile en haut de l'espace adresse ? Je ne pensais pas qu'on pouvait le modifier
[...]
Ca marche plutot bien en apparence, et je me sert de cette classe comme base pour le polymorphisme.
C'est que tu n'en as pas essayé les cas que j'ai énumérés ci-dessus.
Effectivement je n'ai pas essayé les creations avec new[] , ni en multi-thread Dans ces cas là, existe -il une solution ?
Par contre j'ai une interrogation, y a t il une autre facon de faire? J'ai utilisé malloc et free, car la fonction globale new appelle une 2eme fois le constructeur ce qui est genant.
La fonction new n'appelle de constructeur. C'est une expression new qui l'appelle. Donc :
p = new Toto ; // appel du constructeur... p = operator new( sizeof Toto ) ; // pas d'appel du constructeur...
La même dichotomie existe entre la fonction delete, et une experssion delete.
Ok, je vois que j'utilisais mal la fonction new.
dug8C
On 24 mar, 11:02, Fabien LE LEZ wrote:
On 24 Mar 2007 02:54:51 -0700, :
J'ai besoin de savoir si je dois appeller delete si CBase1 est créée sur le tas.
Utilise un GC, et comme ça tu n'auras jamais besoin d'appeler delete.
Oui j'y ai pensé aussi mais d'après que ce j'en sais le GC est un "ramasse-miette" , c'est à dire qu'il ne libere la mémoire qu'à la fin du programme ?
Mais si j'alloue de grande quantité de memoire ( par rapport à la memoire disponible ) et que je libère qu'à la fin, tout le long du programme de la memoire sera allouée alors qu'elle ne sert peut-être pas ?
On 24 mar, 11:02, Fabien LE LEZ <grams...@gramster.com> wrote:
On 24 Mar 2007 02:54:51 -0700, d...@hotmail.com:
J'ai besoin de savoir si je dois appeller delete si CBase1 est créée
sur le tas.
Utilise un GC, et comme ça tu n'auras jamais besoin d'appeler delete.
Oui j'y ai pensé aussi mais d'après que ce j'en sais le GC est un
"ramasse-miette" , c'est à dire qu'il ne libere la mémoire qu'à la fin
du programme ?
Mais si j'alloue de grande quantité de memoire ( par rapport à la
memoire disponible ) et que je libère qu'à la fin, tout le long du
programme de la memoire sera allouée alors qu'elle ne sert peut-être
pas ?
J'ai besoin de savoir si je dois appeller delete si CBase1 est créée sur le tas.
Utilise un GC, et comme ça tu n'auras jamais besoin d'appeler delete.
Oui j'y ai pensé aussi mais d'après que ce j'en sais le GC est un "ramasse-miette" , c'est à dire qu'il ne libere la mémoire qu'à la fin du programme ?
Mais si j'alloue de grande quantité de memoire ( par rapport à la memoire disponible ) et que je libère qu'à la fin, tout le long du programme de la memoire sera allouée alors qu'elle ne sert peut-être pas ?
Fabien LE LEZ
On 24 Mar 2007 03:18:10 -0700, :
Oui j'y ai pensé aussi mais d'après que ce j'en sais le GC est un "ramasse-miette" ,
Oui.
c'est à dire qu'il ne libere la mémoire qu'à la fin du programme ?
Non. Ça, c'est fait par l'OS de toutes façons, quel que soit le programme.
Un GC est censé libérer la mémoire dès qu'un objet n'est plus utilisé.
On 24 Mar 2007 03:18:10 -0700, dug8C@hotmail.com:
Oui j'y ai pensé aussi mais d'après que ce j'en sais le GC est un
"ramasse-miette" ,
Oui.
c'est à dire qu'il ne libere la mémoire qu'à la fin
du programme ?
Non. Ça, c'est fait par l'OS de toutes façons, quel que soit le
programme.
Un GC est censé libérer la mémoire dès qu'un objet n'est plus utilisé.
Un GC est censé libérer la mémoire dès qu'un objet n'est plus utilisé.
Pas "dès qu'", mais "à un moment après qu'... s'il en a envie".
-- Loïc
James Kanze
On Mar 24, 3:03 pm, Loïc Joly wrote:
Un GC est censé libérer la mémoire dès qu'un objet n'est plus u tilisé.
Pas "dès qu'", mais "à un moment après qu'... s'il en a envie".
Ça dépend de ce que tu entends par « libérer ».
D'abord, ni les glaneurs de cellules, ni les implémentations de malloc/free que j'utilise ne libèrent la mémoire au système. Strictement parlant, ils ne la libèrent jamais ; ils s'arrangent pour le réutiliser dans le processus même. Si un processus utilise beaucoup de mémoire dynamique pendant une courte durée, cette mémoire reste « perdue » jusqu'à la fin du processus. En principe, et un glaneur de cellules et malloc/free pourraient libérer la mémoire au système. Dans la pratique, en revanche, ça ne marche bien que dans le cas des glaneurs de cellules qui déplacent la mémoire (et qui donc finissent par avoir toute la mémoire libre dans un bloc unique), et de tels glaneurs de cellules ne marchent pas réelement avec le C++.
Ensuite, évidemment, à l'intérieur du processus... la mémoire est libérée dans la mesure où elle est disponible lors de la prochaine démande d'allocation. C'est vrai qu'avec un glaneur de cellules, on ne la réutilisera qu'après un passage par le collecteur, qui ne sera déclenché que s'il y a besoin. Mais dans la pratique, certains malloc/free ne se comportent pas différemment -- la seule différence, c'est qu'avec le malloc/free, c'est l'appel de free qui positionne le drappeau que le bloc est libre, tandis qu'un glaneur de cellules s'en aperçoit tout seul. (Pour des raisons de mise au point, il est souvent préférable de ne pas récycler la mémoire tout de suite, et des outils tel que Purify la retient aussi longtemps que possible avant de la réutiliser.)
-- James Kanze (Gabi Software) email: 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
On Mar 24, 3:03 pm, Loïc Joly <loic.actarus.j...@numericable.fr>
wrote:
Un GC est censé libérer la mémoire dès qu'un objet n'est plus u tilisé.
Pas "dès qu'", mais "à un moment après qu'... s'il en a envie".
Ça dépend de ce que tu entends par « libérer ».
D'abord, ni les glaneurs de cellules, ni les implémentations de
malloc/free que j'utilise ne libèrent la mémoire au système.
Strictement parlant, ils ne la libèrent jamais ; ils
s'arrangent pour le réutiliser dans le processus même. Si un
processus utilise beaucoup de mémoire dynamique pendant une
courte durée, cette mémoire reste « perdue » jusqu'à la fin du
processus. En principe, et un glaneur de cellules et
malloc/free pourraient libérer la mémoire au système. Dans la
pratique, en revanche, ça ne marche bien que dans le cas des
glaneurs de cellules qui déplacent la mémoire (et qui donc
finissent par avoir toute la mémoire libre dans un bloc unique),
et de tels glaneurs de cellules ne marchent pas réelement avec
le C++.
Ensuite, évidemment, à l'intérieur du processus... la mémoire
est libérée dans la mesure où elle est disponible lors de la
prochaine démande d'allocation. C'est vrai qu'avec un glaneur de
cellules, on ne la réutilisera qu'après un passage par le
collecteur, qui ne sera déclenché que s'il y a besoin. Mais dans
la pratique, certains malloc/free ne se comportent pas
différemment -- la seule différence, c'est qu'avec le
malloc/free, c'est l'appel de free qui positionne le drappeau
que le bloc est libre, tandis qu'un glaneur de cellules s'en
aperçoit tout seul. (Pour des raisons de mise au point, il est
souvent préférable de ne pas récycler la mémoire tout de suite,
et des outils tel que Purify la retient aussi longtemps que
possible avant de la réutiliser.)
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
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
Un GC est censé libérer la mémoire dès qu'un objet n'est plus u tilisé.
Pas "dès qu'", mais "à un moment après qu'... s'il en a envie".
Ça dépend de ce que tu entends par « libérer ».
D'abord, ni les glaneurs de cellules, ni les implémentations de malloc/free que j'utilise ne libèrent la mémoire au système. Strictement parlant, ils ne la libèrent jamais ; ils s'arrangent pour le réutiliser dans le processus même. Si un processus utilise beaucoup de mémoire dynamique pendant une courte durée, cette mémoire reste « perdue » jusqu'à la fin du processus. En principe, et un glaneur de cellules et malloc/free pourraient libérer la mémoire au système. Dans la pratique, en revanche, ça ne marche bien que dans le cas des glaneurs de cellules qui déplacent la mémoire (et qui donc finissent par avoir toute la mémoire libre dans un bloc unique), et de tels glaneurs de cellules ne marchent pas réelement avec le C++.
Ensuite, évidemment, à l'intérieur du processus... la mémoire est libérée dans la mesure où elle est disponible lors de la prochaine démande d'allocation. C'est vrai qu'avec un glaneur de cellules, on ne la réutilisera qu'après un passage par le collecteur, qui ne sera déclenché que s'il y a besoin. Mais dans la pratique, certains malloc/free ne se comportent pas différemment -- la seule différence, c'est qu'avec le malloc/free, c'est l'appel de free qui positionne le drappeau que le bloc est libre, tandis qu'un glaneur de cellules s'en aperçoit tout seul. (Pour des raisons de mise au point, il est souvent préférable de ne pas récycler la mémoire tout de suite, et des outils tel que Purify la retient aussi longtemps que possible avant de la réutiliser.)
-- James Kanze (Gabi Software) email: 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