On Mar 24, 8:18 pm, Jean-Marc Bourguet wrote:"James Kanze" writes:Le hardware du PDP-11 mettait une forte penalité si char n'était pas
signé. Du coup, char est signé sous tous les Unix que je connais,
AIX a un char non signé.
Intéressant. Est-ce qu'il y a une différence de performance entre les
deux ? (Sur un gros IBM, je sais que charger un char signé dans un
régistre coute, ou au moins a coûté, nettement plus cher que d'en charger
un non-signé.)
On Mar 24, 8:18 pm, Jean-Marc Bourguet <j...@bourguet.org> wrote:
"James Kanze" <james.ka...@gmail.com> writes:
Le hardware du PDP-11 mettait une forte penalité si char n'était pas
signé. Du coup, char est signé sous tous les Unix que je connais,
AIX a un char non signé.
Intéressant. Est-ce qu'il y a une différence de performance entre les
deux ? (Sur un gros IBM, je sais que charger un char signé dans un
régistre coute, ou au moins a coûté, nettement plus cher que d'en charger
un non-signé.)
On Mar 24, 8:18 pm, Jean-Marc Bourguet wrote:"James Kanze" writes:Le hardware du PDP-11 mettait une forte penalité si char n'était pas
signé. Du coup, char est signé sous tous les Unix que je connais,
AIX a un char non signé.
Intéressant. Est-ce qu'il y a une différence de performance entre les
deux ? (Sur un gros IBM, je sais que charger un char signé dans un
régistre coute, ou au moins a coûté, nettement plus cher que d'en charger
un non-signé.)
"James Kanze" writes:On Mar 24, 8:18 pm, Jean-Marc Bourguet wrote:"James Kanze" writes:Le hardware du PDP-11 mettait une forte penalité si char n'étai t pas
signé. Du coup, char est signé sous tous les Unix que je connai s,
AIX a un char non signé.
Intéressant. Est-ce qu'il y a une différence de performance entre l es
deux ? (Sur un gros IBM, je sais que charger un char signé dans un
régistre coute, ou au moins a coûté, nettement plus cher que d'en charger
un non-signé.)
Je n'ai jamais fait de mesures.
Je sais qu'AIX a un char non signe parce
qu'une lib que nous utilisions avait le bug classique de stocker le
resultat de fgetc dans un char. La boucle infinie qui en resulte avec un
char non signe est beaucoup plus visible que le fait que le caractere de
code 255 soit confondu avec la fin de fichier.
"James Kanze" <james.ka...@gmail.com> writes:
On Mar 24, 8:18 pm, Jean-Marc Bourguet <j...@bourguet.org> wrote:
"James Kanze" <james.ka...@gmail.com> writes:
Le hardware du PDP-11 mettait une forte penalité si char n'étai t pas
signé. Du coup, char est signé sous tous les Unix que je connai s,
AIX a un char non signé.
Intéressant. Est-ce qu'il y a une différence de performance entre l es
deux ? (Sur un gros IBM, je sais que charger un char signé dans un
régistre coute, ou au moins a coûté, nettement plus cher que d'en charger
un non-signé.)
Je n'ai jamais fait de mesures.
Je sais qu'AIX a un char non signe parce
qu'une lib que nous utilisions avait le bug classique de stocker le
resultat de fgetc dans un char. La boucle infinie qui en resulte avec un
char non signe est beaucoup plus visible que le fait que le caractere de
code 255 soit confondu avec la fin de fichier.
"James Kanze" writes:On Mar 24, 8:18 pm, Jean-Marc Bourguet wrote:"James Kanze" writes:Le hardware du PDP-11 mettait une forte penalité si char n'étai t pas
signé. Du coup, char est signé sous tous les Unix que je connai s,
AIX a un char non signé.
Intéressant. Est-ce qu'il y a une différence de performance entre l es
deux ? (Sur un gros IBM, je sais que charger un char signé dans un
régistre coute, ou au moins a coûté, nettement plus cher que d'en charger
un non-signé.)
Je n'ai jamais fait de mesures.
Je sais qu'AIX a un char non signe parce
qu'une lib que nous utilisions avait le bug classique de stocker le
resultat de fgetc dans un char. La boucle infinie qui en resulte avec un
char non signe est beaucoup plus visible que le fait que le caractere de
code 255 soit confondu avec la fin de fichier.
Et tu marques tous les éléments dans le tableau ? Mais ça
devient compliqué, ton histoire ; il faut que tu notes s'il
faut delete ou non, puis s'il faut delete ou delete[]. Et
qu'est-ce qui se passe si tu as un pointeur initialisé avec
quelque chose comme &array[3] ? Il faut alors noter si l'objet
est le premier dans le tableau ou non. Et que se passe-t-il si
l'utilisateur du premier élément décide qu'il a fini (et donc,
qu'il faut faire delete), et qu'un utilisateur d'un des autres
-> éléments n'en a pas fini ?
Je ne sais pas quel problème tu cherches à résoudre, mais j'ai
l'impression que c'est la fuite en avant.
void* operator new[]( unsigned bytes )
{
nb_elem = bytes / sizeof(CBase1) ;
Ce qui n'est pas forcement juste. Le nombre réel en serait bien
inférieur à nb_elem, jamais strictement supérieur, mais nb_elem
peut bien être strictement supérieur au nombre d'éléments.
creation_dyn_tb = true;
void* result = ::operator new [] ( bytes );
Et que se passe-t-il si ::operator new[] lève une exception ?
il manque un throw bad_alloc()
int
main()
{
Toto* array = new Toto[ 5 ] ;
std::cout << "allocated 5 Toto dynamically" << std::endl ;
for ( int i = 0 ; i < 5 ; ++ i ) {
if ( ! array[ i ].isDym ) {
std::cout << "Oops: not dynamic" << std::endl ;
}
}
Toto local ;
if ( local.isDym ) {
std::cout << "Oops: dynamic" << std::endl ;
}
delete array ;
return 0 ;
}
renvoie :
allocated 5 Toto dynamically
Oops: dynamic
Salut
Segmentation fault
Ce n'est pas ce que j'appellerai « marcher ». (À vrai dire, ça
me semblait évident que cet exemple ne pourrait pas marcher.)
D'un autre cote c'est normal vu que tu créés avec new[] et que tu
En multi-thread c'est aléatoire, ça peut ne pas marcher si un thread
cree un tableau sur le tas
tant dis qu'un autre en crée un sur la pile puisqu'ils utilise la m ême
variable
statique.
En somme, ça ne marche pas.
Exact :)
Si j'ai bien compris, le std::set sert à la construction pour verifier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le tas ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Et tu marques tous les éléments dans le tableau ? Mais ça
devient compliqué, ton histoire ; il faut que tu notes s'il
faut delete ou non, puis s'il faut delete ou delete[]. Et
qu'est-ce qui se passe si tu as un pointeur initialisé avec
quelque chose comme &array[3] ? Il faut alors noter si l'objet
est le premier dans le tableau ou non. Et que se passe-t-il si
l'utilisateur du premier élément décide qu'il a fini (et donc,
qu'il faut faire delete), et qu'un utilisateur d'un des autres
-> éléments n'en a pas fini ?
Je ne sais pas quel problème tu cherches à résoudre, mais j'ai
l'impression que c'est la fuite en avant.
void* operator new[]( unsigned bytes )
{
nb_elem = bytes / sizeof(CBase1) ;
Ce qui n'est pas forcement juste. Le nombre réel en serait bien
inférieur à nb_elem, jamais strictement supérieur, mais nb_elem
peut bien être strictement supérieur au nombre d'éléments.
creation_dyn_tb = true;
void* result = ::operator new [] ( bytes );
Et que se passe-t-il si ::operator new[] lève une exception ?
il manque un throw bad_alloc()
int
main()
{
Toto* array = new Toto[ 5 ] ;
std::cout << "allocated 5 Toto dynamically" << std::endl ;
for ( int i = 0 ; i < 5 ; ++ i ) {
if ( ! array[ i ].isDym ) {
std::cout << "Oops: not dynamic" << std::endl ;
}
}
Toto local ;
if ( local.isDym ) {
std::cout << "Oops: dynamic" << std::endl ;
}
delete array ;
return 0 ;
}
renvoie :
allocated 5 Toto dynamically
Oops: dynamic
Salut
Segmentation fault
Ce n'est pas ce que j'appellerai « marcher ». (À vrai dire, ça
me semblait évident que cet exemple ne pourrait pas marcher.)
D'un autre cote c'est normal vu que tu créés avec new[] et que tu
En multi-thread c'est aléatoire, ça peut ne pas marcher si un thread
cree un tableau sur le tas
tant dis qu'un autre en crée un sur la pile puisqu'ils utilise la m ême
variable
statique.
En somme, ça ne marche pas.
Exact :)
Si j'ai bien compris, le std::set sert à la construction pour verifier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le tas ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Et tu marques tous les éléments dans le tableau ? Mais ça
devient compliqué, ton histoire ; il faut que tu notes s'il
faut delete ou non, puis s'il faut delete ou delete[]. Et
qu'est-ce qui se passe si tu as un pointeur initialisé avec
quelque chose comme &array[3] ? Il faut alors noter si l'objet
est le premier dans le tableau ou non. Et que se passe-t-il si
l'utilisateur du premier élément décide qu'il a fini (et donc,
qu'il faut faire delete), et qu'un utilisateur d'un des autres
-> éléments n'en a pas fini ?
Je ne sais pas quel problème tu cherches à résoudre, mais j'ai
l'impression que c'est la fuite en avant.
void* operator new[]( unsigned bytes )
{
nb_elem = bytes / sizeof(CBase1) ;
Ce qui n'est pas forcement juste. Le nombre réel en serait bien
inférieur à nb_elem, jamais strictement supérieur, mais nb_elem
peut bien être strictement supérieur au nombre d'éléments.
creation_dyn_tb = true;
void* result = ::operator new [] ( bytes );
Et que se passe-t-il si ::operator new[] lève une exception ?
il manque un throw bad_alloc()
int
main()
{
Toto* array = new Toto[ 5 ] ;
std::cout << "allocated 5 Toto dynamically" << std::endl ;
for ( int i = 0 ; i < 5 ; ++ i ) {
if ( ! array[ i ].isDym ) {
std::cout << "Oops: not dynamic" << std::endl ;
}
}
Toto local ;
if ( local.isDym ) {
std::cout << "Oops: dynamic" << std::endl ;
}
delete array ;
return 0 ;
}
renvoie :
allocated 5 Toto dynamically
Oops: dynamic
Salut
Segmentation fault
Ce n'est pas ce que j'appellerai « marcher ». (À vrai dire, ça
me semblait évident que cet exemple ne pourrait pas marcher.)
D'un autre cote c'est normal vu que tu créés avec new[] et que tu
En multi-thread c'est aléatoire, ça peut ne pas marcher si un thread
cree un tableau sur le tas
tant dis qu'un autre en crée un sur la pile puisqu'ils utilise la m ême
variable
statique.
En somme, ça ne marche pas.
Exact :)
Si j'ai bien compris, le std::set sert à la construction pour verifier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le tas ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Et tu marques tous les éléments dans le tableau ? Mais ça
devient compliqué, ton histoire ; il faut que tu notes s'il
faut delete ou non, puis s'il faut delete ou delete[]. Et
qu'est-ce qui se passe si tu as un pointeur initialisé avec
quelque chose comme &array[3] ? Il faut alors noter si l'objet
est le premier dans le tableau ou non. Et que se passe-t-il si
l'utilisateur du premier élément décide qu'il a fini (et donc,
qu'il faut faire delete), et qu'un utilisateur d'un des autres
-> éléments n'en a pas fini ?Je ne sais pas quel problème tu cherches à résoudre, mais j'ai
l'impression que c'est la fuite en avant.
Je crois que je me suis un peu perdu dans mon raisonnement...void* operator new[]( unsigned bytes )
{
nb_elem = bytes / sizeof(CBase1) ;
Ce qui n'est pas forcement juste. Le nombre réel en serait bien
inférieur à nb_elem, jamais strictement supérieur, mais nb_elem
peut bien être strictement supérieur au nombre d'éléments.
Je me suis apercu en faisant des essais que nb_elem = ( bytes - 4 ) /
sizeof(CBase1)
mais c'est peut-être spécifique à mon OS.creation_dyn_tb = true;
void* result = ::operator new [] ( bytes );
Et que se passe-t-il si ::operator new[] lève une exception ?
il manque un throw bad_alloc()
[...]int
main()
{
Toto* array = new Toto[ 5 ] ;
std::cout << "allocated 5 Toto dynamically" << std::endl ;
for ( int i = 0 ; i < 5 ; ++ i ) {
if ( ! array[ i ].isDym ) {
std::cout << "Oops: not dynamic" << std::endl ;
}
}
Toto local ;
if ( local.isDym ) {
std::cout << "Oops: dynamic" << std::endl ;
}
delete array ;
return 0 ;
}
renvoie :
allocated 5 Toto dynamically
Oops: dynamic
Salut
Segmentation fault
Ce n'est pas ce que j'appellerai « marcher ». (À vrai dire, ça
me semblait évident que cet exemple ne pourrait pas marcher.)
D'un autre cote c'est normal vu que tu créés avec new[] et que tu
libères avec delete.
Si local "se voit" Dynamic c'est parce que que le nombre d'elements
est mal calculé.
Mais c'est une erreur de ma part de marquer les objets dans le
tableau, comme créés sur le tas.
Il faut les marquer comme créé sur la pile, vu qu'ils ne seront pas
detruit un par un, mais l'ensemble du tableau à la fois .
dans ton exemple ca devient :
void*
Toto::operator new[](
size_t n )
{
void* result = ::operator new[]( n ) ;
allocCount = 0;
return result ;
}
Merci pour les explications et le temps passé, je vais revoir tout ça
à tête reposée .En multi-thread c'est aléatoire, ça peut ne pas marcher si un thr ead
cree un tableau sur le tas
tant dis qu'un autre en crée un sur la pile puisqu'ils utilise la m ême
variable
statique.
En somme, ça ne marche pas.
Exact :)Si j'ai bien compris, le std::set sert à la construction pour verif ier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le tas ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Je suis pas persuadé d'avoir besoin de stocker les adresses des
pointeurs.
Pour savoir si on appelle delete, autant mettre l'info dans l'objet
lors
de sa construction et de disposer de cette info à sa destruction.
Les objets sont détruits par une autre classe, qui va appeller delete
au vu de cette info:
- Si l'objet a été créés avec new , on appelera delete.
- S'il a été crées sans new, pas d'appel à delete.
- S'il fait partie d'un tableau, pas d'appel à delete : il sera
détruit lors de la
destruction du tableau avec le delete[]
D'autre part cette classe ne gère q'un objet à la fois et pas des
tableaux, donc ca simplifie le problème.
Et tu marques tous les éléments dans le tableau ? Mais ça
devient compliqué, ton histoire ; il faut que tu notes s'il
faut delete ou non, puis s'il faut delete ou delete[]. Et
qu'est-ce qui se passe si tu as un pointeur initialisé avec
quelque chose comme &array[3] ? Il faut alors noter si l'objet
est le premier dans le tableau ou non. Et que se passe-t-il si
l'utilisateur du premier élément décide qu'il a fini (et donc,
qu'il faut faire delete), et qu'un utilisateur d'un des autres
-> éléments n'en a pas fini ?
Je ne sais pas quel problème tu cherches à résoudre, mais j'ai
l'impression que c'est la fuite en avant.
Je crois que je me suis un peu perdu dans mon raisonnement...
void* operator new[]( unsigned bytes )
{
nb_elem = bytes / sizeof(CBase1) ;
Ce qui n'est pas forcement juste. Le nombre réel en serait bien
inférieur à nb_elem, jamais strictement supérieur, mais nb_elem
peut bien être strictement supérieur au nombre d'éléments.
Je me suis apercu en faisant des essais que nb_elem = ( bytes - 4 ) /
sizeof(CBase1)
mais c'est peut-être spécifique à mon OS.
creation_dyn_tb = true;
void* result = ::operator new [] ( bytes );
Et que se passe-t-il si ::operator new[] lève une exception ?
il manque un throw bad_alloc()
[...]
int
main()
{
Toto* array = new Toto[ 5 ] ;
std::cout << "allocated 5 Toto dynamically" << std::endl ;
for ( int i = 0 ; i < 5 ; ++ i ) {
if ( ! array[ i ].isDym ) {
std::cout << "Oops: not dynamic" << std::endl ;
}
}
Toto local ;
if ( local.isDym ) {
std::cout << "Oops: dynamic" << std::endl ;
}
delete array ;
return 0 ;
}
renvoie :
allocated 5 Toto dynamically
Oops: dynamic
Salut
Segmentation fault
Ce n'est pas ce que j'appellerai « marcher ». (À vrai dire, ça
me semblait évident que cet exemple ne pourrait pas marcher.)
D'un autre cote c'est normal vu que tu créés avec new[] et que tu
libères avec delete.
Si local "se voit" Dynamic c'est parce que que le nombre d'elements
est mal calculé.
Mais c'est une erreur de ma part de marquer les objets dans le
tableau, comme créés sur le tas.
Il faut les marquer comme créé sur la pile, vu qu'ils ne seront pas
detruit un par un, mais l'ensemble du tableau à la fois .
dans ton exemple ca devient :
void*
Toto::operator new[](
size_t n )
{
void* result = ::operator new[]( n ) ;
allocCount = 0;
return result ;
}
Merci pour les explications et le temps passé, je vais revoir tout ça
à tête reposée .
En multi-thread c'est aléatoire, ça peut ne pas marcher si un thr ead
cree un tableau sur le tas
tant dis qu'un autre en crée un sur la pile puisqu'ils utilise la m ême
variable
statique.
En somme, ça ne marche pas.
Exact :)
Si j'ai bien compris, le std::set sert à la construction pour verif ier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le tas ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Je suis pas persuadé d'avoir besoin de stocker les adresses des
pointeurs.
Pour savoir si on appelle delete, autant mettre l'info dans l'objet
lors
de sa construction et de disposer de cette info à sa destruction.
Les objets sont détruits par une autre classe, qui va appeller delete
au vu de cette info:
- Si l'objet a été créés avec new , on appelera delete.
- S'il a été crées sans new, pas d'appel à delete.
- S'il fait partie d'un tableau, pas d'appel à delete : il sera
détruit lors de la
destruction du tableau avec le delete[]
D'autre part cette classe ne gère q'un objet à la fois et pas des
tableaux, donc ca simplifie le problème.
Et tu marques tous les éléments dans le tableau ? Mais ça
devient compliqué, ton histoire ; il faut que tu notes s'il
faut delete ou non, puis s'il faut delete ou delete[]. Et
qu'est-ce qui se passe si tu as un pointeur initialisé avec
quelque chose comme &array[3] ? Il faut alors noter si l'objet
est le premier dans le tableau ou non. Et que se passe-t-il si
l'utilisateur du premier élément décide qu'il a fini (et donc,
qu'il faut faire delete), et qu'un utilisateur d'un des autres
-> éléments n'en a pas fini ?Je ne sais pas quel problème tu cherches à résoudre, mais j'ai
l'impression que c'est la fuite en avant.
Je crois que je me suis un peu perdu dans mon raisonnement...void* operator new[]( unsigned bytes )
{
nb_elem = bytes / sizeof(CBase1) ;
Ce qui n'est pas forcement juste. Le nombre réel en serait bien
inférieur à nb_elem, jamais strictement supérieur, mais nb_elem
peut bien être strictement supérieur au nombre d'éléments.
Je me suis apercu en faisant des essais que nb_elem = ( bytes - 4 ) /
sizeof(CBase1)
mais c'est peut-être spécifique à mon OS.creation_dyn_tb = true;
void* result = ::operator new [] ( bytes );
Et que se passe-t-il si ::operator new[] lève une exception ?
il manque un throw bad_alloc()
[...]int
main()
{
Toto* array = new Toto[ 5 ] ;
std::cout << "allocated 5 Toto dynamically" << std::endl ;
for ( int i = 0 ; i < 5 ; ++ i ) {
if ( ! array[ i ].isDym ) {
std::cout << "Oops: not dynamic" << std::endl ;
}
}
Toto local ;
if ( local.isDym ) {
std::cout << "Oops: dynamic" << std::endl ;
}
delete array ;
return 0 ;
}
renvoie :
allocated 5 Toto dynamically
Oops: dynamic
Salut
Segmentation fault
Ce n'est pas ce que j'appellerai « marcher ». (À vrai dire, ça
me semblait évident que cet exemple ne pourrait pas marcher.)
D'un autre cote c'est normal vu que tu créés avec new[] et que tu
libères avec delete.
Si local "se voit" Dynamic c'est parce que que le nombre d'elements
est mal calculé.
Mais c'est une erreur de ma part de marquer les objets dans le
tableau, comme créés sur le tas.
Il faut les marquer comme créé sur la pile, vu qu'ils ne seront pas
detruit un par un, mais l'ensemble du tableau à la fois .
dans ton exemple ca devient :
void*
Toto::operator new[](
size_t n )
{
void* result = ::operator new[]( n ) ;
allocCount = 0;
return result ;
}
Merci pour les explications et le temps passé, je vais revoir tout ça
à tête reposée .En multi-thread c'est aléatoire, ça peut ne pas marcher si un thr ead
cree un tableau sur le tas
tant dis qu'un autre en crée un sur la pile puisqu'ils utilise la m ême
variable
statique.
En somme, ça ne marche pas.
Exact :)Si j'ai bien compris, le std::set sert à la construction pour verif ier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le tas ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Je suis pas persuadé d'avoir besoin de stocker les adresses des
pointeurs.
Pour savoir si on appelle delete, autant mettre l'info dans l'objet
lors
de sa construction et de disposer de cette info à sa destruction.
Les objets sont détruits par une autre classe, qui va appeller delete
au vu de cette info:
- Si l'objet a été créés avec new , on appelera delete.
- S'il a été crées sans new, pas d'appel à delete.
- S'il fait partie d'un tableau, pas d'appel à delete : il sera
détruit lors de la
destruction du tableau avec le delete[]
D'autre part cette classe ne gère q'un objet à la fois et pas des
tableaux, donc ca simplifie le problème.
Ce qui n'est pas forcement juste. Le nombre réel en serait bien
inférieur à nb_elem, jamais strictement supérieur, mais nb_elem
peut bien être strictement supérieur au nombre d'éléments.
Je me suis apercu en faisant des essais que nb_elem = ( bytes - 4 ) /
sizeof(CBase1)
mais c'est peut-être spécifique à mon OS.
creation_dyn_tb = true;
void* result = ::operator new [] ( bytes );
Et que se passe-t-il si ::operator new[] lève une exception ?
il manque un throw bad_alloc()
[...]int
main()
{
Toto* array = new Toto[ 5 ] ;
std::cout << "allocated 5 Toto dynamically" << std::endl ;
for ( int i = 0 ; i < 5 ; ++ i ) {
if ( ! array[ i ].isDym ) {
std::cout << "Oops: not dynamic" << std::endl ;
}
}
Toto local ;
if ( local.isDym ) {
std::cout << "Oops: dynamic" << std::endl ;
}
delete array ;
return 0 ;
}
renvoie :
allocated 5 Toto dynamically
Oops: dynamic
Salut
Segmentation fault
Ce n'est pas ce que j'appellerai « marcher ». (À vrai dire, ça
me semblait évident que cet exemple ne pourrait pas marcher.)
D'un autre cote c'est normal vu que tu créés avec new[] et que tu
libères avec delete.
Si local "se voit" Dynamic c'est parce que que le nombre d'elements
est mal calculé.
Mais c'est une erreur de ma part de marquer les objets dans le
tableau, comme créés sur le tas.
Il faut les marquer comme créé sur la pile, vu qu'ils ne seront pas
detruit un par un, mais l'ensemble du tableau à la fois .
dans ton exemple ca devient :
Si j'ai bien compris, le std::set sert à la construction pour verif ier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le tas ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Je suis pas persuadé d'avoir besoin de stocker les adresses des
pointeurs.
Pour savoir si on appelle delete, autant mettre l'info dans l'objet
lors
de sa construction et de disposer de cette info à sa destruction.
Les objets sont détruits par une autre classe, qui va appeller delete
au vu de cette info:
- Si l'objet a été créés avec new , on appelera delete.
- S'il a été crées sans new, pas d'appel à delete.
- S'il fait partie d'un tableau, pas d'appel à delete : il sera
détruit lors de la
destruction du tableau avec le delete[]
Ce qui n'est pas forcement juste. Le nombre réel en serait bien
inférieur à nb_elem, jamais strictement supérieur, mais nb_elem
peut bien être strictement supérieur au nombre d'éléments.
Je me suis apercu en faisant des essais que nb_elem = ( bytes - 4 ) /
sizeof(CBase1)
mais c'est peut-être spécifique à mon OS.
creation_dyn_tb = true;
void* result = ::operator new [] ( bytes );
Et que se passe-t-il si ::operator new[] lève une exception ?
il manque un throw bad_alloc()
[...]
int
main()
{
Toto* array = new Toto[ 5 ] ;
std::cout << "allocated 5 Toto dynamically" << std::endl ;
for ( int i = 0 ; i < 5 ; ++ i ) {
if ( ! array[ i ].isDym ) {
std::cout << "Oops: not dynamic" << std::endl ;
}
}
Toto local ;
if ( local.isDym ) {
std::cout << "Oops: dynamic" << std::endl ;
}
delete array ;
return 0 ;
}
renvoie :
allocated 5 Toto dynamically
Oops: dynamic
Salut
Segmentation fault
Ce n'est pas ce que j'appellerai « marcher ». (À vrai dire, ça
me semblait évident que cet exemple ne pourrait pas marcher.)
D'un autre cote c'est normal vu que tu créés avec new[] et que tu
libères avec delete.
Si local "se voit" Dynamic c'est parce que que le nombre d'elements
est mal calculé.
Mais c'est une erreur de ma part de marquer les objets dans le
tableau, comme créés sur le tas.
Il faut les marquer comme créé sur la pile, vu qu'ils ne seront pas
detruit un par un, mais l'ensemble du tableau à la fois .
dans ton exemple ca devient :
Si j'ai bien compris, le std::set sert à la construction pour verif ier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le tas ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Je suis pas persuadé d'avoir besoin de stocker les adresses des
pointeurs.
Pour savoir si on appelle delete, autant mettre l'info dans l'objet
lors
de sa construction et de disposer de cette info à sa destruction.
Les objets sont détruits par une autre classe, qui va appeller delete
au vu de cette info:
- Si l'objet a été créés avec new , on appelera delete.
- S'il a été crées sans new, pas d'appel à delete.
- S'il fait partie d'un tableau, pas d'appel à delete : il sera
détruit lors de la
destruction du tableau avec le delete[]
Ce qui n'est pas forcement juste. Le nombre réel en serait bien
inférieur à nb_elem, jamais strictement supérieur, mais nb_elem
peut bien être strictement supérieur au nombre d'éléments.
Je me suis apercu en faisant des essais que nb_elem = ( bytes - 4 ) /
sizeof(CBase1)
mais c'est peut-être spécifique à mon OS.
creation_dyn_tb = true;
void* result = ::operator new [] ( bytes );
Et que se passe-t-il si ::operator new[] lève une exception ?
il manque un throw bad_alloc()
[...]int
main()
{
Toto* array = new Toto[ 5 ] ;
std::cout << "allocated 5 Toto dynamically" << std::endl ;
for ( int i = 0 ; i < 5 ; ++ i ) {
if ( ! array[ i ].isDym ) {
std::cout << "Oops: not dynamic" << std::endl ;
}
}
Toto local ;
if ( local.isDym ) {
std::cout << "Oops: dynamic" << std::endl ;
}
delete array ;
return 0 ;
}
renvoie :
allocated 5 Toto dynamically
Oops: dynamic
Salut
Segmentation fault
Ce n'est pas ce que j'appellerai « marcher ». (À vrai dire, ça
me semblait évident que cet exemple ne pourrait pas marcher.)
D'un autre cote c'est normal vu que tu créés avec new[] et que tu
libères avec delete.
Si local "se voit" Dynamic c'est parce que que le nombre d'elements
est mal calculé.
Mais c'est une erreur de ma part de marquer les objets dans le
tableau, comme créés sur le tas.
Il faut les marquer comme créé sur la pile, vu qu'ils ne seront pas
detruit un par un, mais l'ensemble du tableau à la fois .
dans ton exemple ca devient :
Si j'ai bien compris, le std::set sert à la construction pour verif ier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le tas ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Je suis pas persuadé d'avoir besoin de stocker les adresses des
pointeurs.
Pour savoir si on appelle delete, autant mettre l'info dans l'objet
lors
de sa construction et de disposer de cette info à sa destruction.
Les objets sont détruits par une autre classe, qui va appeller delete
au vu de cette info:
- Si l'objet a été créés avec new , on appelera delete.
- S'il a été crées sans new, pas d'appel à delete.
- S'il fait partie d'un tableau, pas d'appel à delete : il sera
détruit lors de la
destruction du tableau avec le delete[]
Le throw, il y est, dans ::operator new. En revanche, l'état de
tes variables statiques... Si tout de suite après, tu crées un
objet sur la pile, tu risques de le considérer comme dynamique
plus tard.
Le problème de base, évidemment, c'est l'integrité
transactionnelle de ce que tu fais.
oui j'avais pas vu cet aspect des choses.
Mais c'est une erreur de ma part de marquer les objets dans le
tableau, comme créés sur le tas.
Il faut les marquer comme créé sur la pile, vu qu'ils ne seront pas
detruit un par un, mais l'ensemble du tableau à la fois .
dans ton exemple ca devient :
Gérer les tableaux, c'est en effet plus compliqué. Parce qu'il
faut savoir quand on peut effacer le tableau complet.
Mais en passant : est-ce que tu as réelement besoin de gérer les
tableau. Moi, dans 15 ans de C++, je ne me suis jamais servi de
new[]. Pas une seule fois. Peut-être suffit-il de déclarer
l'operator new[] privé, sans en donner une implémentation.
(Mais pour répondre à ce genre de question, il faudrait savoir
exactement ce que tu essaies de faire.)
Si j'ai bien compris, le std::set sert à la construction pour ver ifier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le ta s ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Je suis pas persuadé d'avoir besoin de stocker les adresses des
pointeurs.
Pour savoir si on appelle delete, autant mettre l'info dans l'objet
lors
de sa construction et de disposer de cette info à sa destruction.
Si on peut le faire de façon fiable.
En passant, à la place de tout ce bazar, est-ce qu'il ne serait
pas plus simple de rendre operator new privé, fournir une
fonction usine ? (Ou mieux, simplement allouer toutes les
instances sur la pile.)
qw<Les objets sont détruits par une autre classe, qui va appeller delete
au vu de cette info:
- Si l'objet a été créés avec new , on appelera delete.
- S'il a été crées sans new, pas d'appel à delete.
- S'il fait partie d'un tableau, pas d'appel à delete : il sera
détruit lors de la
destruction du tableau avec le delete[]
Mais la grande question est : pourquoi ? Ça me semble tordu,
mais je ne sais pas pourquoi tu veux le faire.
Le throw, il y est, dans ::operator new. En revanche, l'état de
tes variables statiques... Si tout de suite après, tu crées un
objet sur la pile, tu risques de le considérer comme dynamique
plus tard.
Le problème de base, évidemment, c'est l'integrité
transactionnelle de ce que tu fais.
oui j'avais pas vu cet aspect des choses.
Mais c'est une erreur de ma part de marquer les objets dans le
tableau, comme créés sur le tas.
Il faut les marquer comme créé sur la pile, vu qu'ils ne seront pas
detruit un par un, mais l'ensemble du tableau à la fois .
dans ton exemple ca devient :
Gérer les tableaux, c'est en effet plus compliqué. Parce qu'il
faut savoir quand on peut effacer le tableau complet.
Mais en passant : est-ce que tu as réelement besoin de gérer les
tableau. Moi, dans 15 ans de C++, je ne me suis jamais servi de
new[]. Pas une seule fois. Peut-être suffit-il de déclarer
l'operator new[] privé, sans en donner une implémentation.
(Mais pour répondre à ce genre de question, il faudrait savoir
exactement ce que tu essaies de faire.)
Si j'ai bien compris, le std::set sert à la construction pour ver ifier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le ta s ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Je suis pas persuadé d'avoir besoin de stocker les adresses des
pointeurs.
Pour savoir si on appelle delete, autant mettre l'info dans l'objet
lors
de sa construction et de disposer de cette info à sa destruction.
Si on peut le faire de façon fiable.
En passant, à la place de tout ce bazar, est-ce qu'il ne serait
pas plus simple de rendre operator new privé, fournir une
fonction usine ? (Ou mieux, simplement allouer toutes les
instances sur la pile.)
qw<
Les objets sont détruits par une autre classe, qui va appeller delete
au vu de cette info:
- Si l'objet a été créés avec new , on appelera delete.
- S'il a été crées sans new, pas d'appel à delete.
- S'il fait partie d'un tableau, pas d'appel à delete : il sera
détruit lors de la
destruction du tableau avec le delete[]
Mais la grande question est : pourquoi ? Ça me semble tordu,
mais je ne sais pas pourquoi tu veux le faire.
Le throw, il y est, dans ::operator new. En revanche, l'état de
tes variables statiques... Si tout de suite après, tu crées un
objet sur la pile, tu risques de le considérer comme dynamique
plus tard.
Le problème de base, évidemment, c'est l'integrité
transactionnelle de ce que tu fais.
oui j'avais pas vu cet aspect des choses.
Mais c'est une erreur de ma part de marquer les objets dans le
tableau, comme créés sur le tas.
Il faut les marquer comme créé sur la pile, vu qu'ils ne seront pas
detruit un par un, mais l'ensemble du tableau à la fois .
dans ton exemple ca devient :
Gérer les tableaux, c'est en effet plus compliqué. Parce qu'il
faut savoir quand on peut effacer le tableau complet.
Mais en passant : est-ce que tu as réelement besoin de gérer les
tableau. Moi, dans 15 ans de C++, je ne me suis jamais servi de
new[]. Pas une seule fois. Peut-être suffit-il de déclarer
l'operator new[] privé, sans en donner une implémentation.
(Mais pour répondre à ce genre de question, il faudrait savoir
exactement ce que tu essaies de faire.)
Si j'ai bien compris, le std::set sert à la construction pour ver ifier
le valeur de this avec celle du set?
Si on la trouve on peut déduire si l'objet est créé sur le ta s ou pas.
Non. Il sert lors du delete. Si on trouve le pointeur dans
l'ensemble, on appelle delete ; sinon, on ne l'appelle pas.
Je suis pas persuadé d'avoir besoin de stocker les adresses des
pointeurs.
Pour savoir si on appelle delete, autant mettre l'info dans l'objet
lors
de sa construction et de disposer de cette info à sa destruction.
Si on peut le faire de façon fiable.
En passant, à la place de tout ce bazar, est-ce qu'il ne serait
pas plus simple de rendre operator new privé, fournir une
fonction usine ? (Ou mieux, simplement allouer toutes les
instances sur la pile.)
qw<Les objets sont détruits par une autre classe, qui va appeller delete
au vu de cette info:
- Si l'objet a été créés avec new , on appelera delete.
- S'il a été crées sans new, pas d'appel à delete.
- S'il fait partie d'un tableau, pas d'appel à delete : il sera
détruit lors de la
destruction du tableau avec le delete[]
Mais la grande question est : pourquoi ? Ça me semble tordu,
mais je ne sais pas pourquoi tu veux le faire.
Ma classe Coque qui gere les CBase1* doit savoir si elle doit faire
delete ou pas.
Elle agit comme un pointeur intelligent et détruit l'instance de
CBase1* lorsque
son compteur d'instance CBase1* est à zéro.
Ma classe Coque qui gere les CBase1* doit savoir si elle doit faire
delete ou pas.
Elle agit comme un pointeur intelligent et détruit l'instance de
CBase1* lorsque
son compteur d'instance CBase1* est à zéro.
Ma classe Coque qui gere les CBase1* doit savoir si elle doit faire
delete ou pas.
Elle agit comme un pointeur intelligent et détruit l'instance de
CBase1* lorsque
son compteur d'instance CBase1* est à zéro.
Il y a alors la solution de boost::shared_ptr : c'est lors de la
création du pointeur initial que l'utilisateur indique qu'il ne
faut pas faire de delete :
Toto t ;
Coque< Toto > p1( &t, non ) ;
Coque< Toto > p2( new Toto, oui ) ;
(Dans le cas de boost::shared_ptr, le « oui » est implicit, et
le « non » prend la forme d'un objet destructeur no-op.)
Ok c'est vrai je n'y avais pas pensé.
N'empêche que d'après mon expérience, des objets tombent dans
des catégories bien distinctes, dont les valeurs et les objets
d'entité. Et que les valeurs ne sont pour ainsi dire jamais
allouées dynamiquement, et qu'on n'en prend jamais l'adresse, et
les objets d'entité sont toujours alloués dynamiquement. Le
problème de savoir si un objet donné a été alloué dynamiquement
ne se pose pour ainsi dire jamais.
Mais il y a des exceptions, surtout dans la catégorie des
agents ; dans mes streambuf filtrants, par exemple, je passe
bien un paramètre supplémentaire pour dire au streambuf s'il
faut qu'il fasse un delete ou non dans son destructeur, et que
j'y pense, j'ai un ou deux autres cas où ça serait utile.
Pas avec un comptage de références, mais d'une façon absolue :
je passe la responsibilité du delete à l'objet, ou je ne le
passe pas. (Mais dans les projets neufs, j'utilise le collecteur
de Boehm. Le problème ne se pose donc pas.)
Il y a alors la solution de boost::shared_ptr : c'est lors de la
création du pointeur initial que l'utilisateur indique qu'il ne
faut pas faire de delete :
Toto t ;
Coque< Toto > p1( &t, non ) ;
Coque< Toto > p2( new Toto, oui ) ;
(Dans le cas de boost::shared_ptr, le « oui » est implicit, et
le « non » prend la forme d'un objet destructeur no-op.)
Ok c'est vrai je n'y avais pas pensé.
N'empêche que d'après mon expérience, des objets tombent dans
des catégories bien distinctes, dont les valeurs et les objets
d'entité. Et que les valeurs ne sont pour ainsi dire jamais
allouées dynamiquement, et qu'on n'en prend jamais l'adresse, et
les objets d'entité sont toujours alloués dynamiquement. Le
problème de savoir si un objet donné a été alloué dynamiquement
ne se pose pour ainsi dire jamais.
Mais il y a des exceptions, surtout dans la catégorie des
agents ; dans mes streambuf filtrants, par exemple, je passe
bien un paramètre supplémentaire pour dire au streambuf s'il
faut qu'il fasse un delete ou non dans son destructeur, et que
j'y pense, j'ai un ou deux autres cas où ça serait utile.
Pas avec un comptage de références, mais d'une façon absolue :
je passe la responsibilité du delete à l'objet, ou je ne le
passe pas. (Mais dans les projets neufs, j'utilise le collecteur
de Boehm. Le problème ne se pose donc pas.)
Il y a alors la solution de boost::shared_ptr : c'est lors de la
création du pointeur initial que l'utilisateur indique qu'il ne
faut pas faire de delete :
Toto t ;
Coque< Toto > p1( &t, non ) ;
Coque< Toto > p2( new Toto, oui ) ;
(Dans le cas de boost::shared_ptr, le « oui » est implicit, et
le « non » prend la forme d'un objet destructeur no-op.)
Ok c'est vrai je n'y avais pas pensé.
N'empêche que d'après mon expérience, des objets tombent dans
des catégories bien distinctes, dont les valeurs et les objets
d'entité. Et que les valeurs ne sont pour ainsi dire jamais
allouées dynamiquement, et qu'on n'en prend jamais l'adresse, et
les objets d'entité sont toujours alloués dynamiquement. Le
problème de savoir si un objet donné a été alloué dynamiquement
ne se pose pour ainsi dire jamais.
Mais il y a des exceptions, surtout dans la catégorie des
agents ; dans mes streambuf filtrants, par exemple, je passe
bien un paramètre supplémentaire pour dire au streambuf s'il
faut qu'il fasse un delete ou non dans son destructeur, et que
j'y pense, j'ai un ou deux autres cas où ça serait utile.
Pas avec un comptage de références, mais d'une façon absolue :
je passe la responsibilité du delete à l'objet, ou je ne le
passe pas. (Mais dans les projets neufs, j'utilise le collecteur
de Boehm. Le problème ne se pose donc pas.)