non seulement table != 0 mais aucune exception bad_alloc est levée.
Il se passe quoi ? Rien ? As-tu fait quelque chose avec ce qui est « alloué » ?
comprends pas :-(
Pourquoi tiens-tu tant à utiliser trop de mémoire ? :-)
D'abord, renvoyer 0 n'est pas une option avec un compilateur conforme (mais c'était encore le cas avec VC6 par exemple, en principe en tout cas).
Par ailleurs, selon les plate-formes, il est tout à fait possible de ne jamais réussir à obtenir un bad_alloc... malheureusement. Ce n'est pas le compilateur C++ qui a le contrôle de l'allocation mémoire, il ne fait que demander l'espace au système d'exploitation. Si le SE dit « OK, voici l'adresse de la mémoire », mais qu'il ne l'alloue pas vraiment tant qu'on n'y accède pas, alors C++ ne peut générer un bad_alloc. Ce comportement est pourtant celui de Linux (par défaut : il semble qu'il soit possible de le modifier).
Sur d'autres SE, avant de pouvoir dire qu'il n'y a plus de mémoire disponible (n'oublions pas la mémoire virtuelle) il se passera beaucoup de choses (swapping et/ou thrashing !) et il est fort possible que le SE ou un programme plus important que le tien plante et bloque tout...
Tu n'as pas dit sur quelle plate-forme tu travailles, alors peut-être que rien de ce que je viens de dire ne s'applique, mais je crois qu'essayer d'avoir un bad_alloc manuellement n'est probablement pas très utile... (il y a des programmes fait exprès pour ce genre de tests)
-- Michel Michaud http://www.gdzid.com FAQ de fr.comp.lang.c++ : http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/
Dans le message 1gx4zft.p7vbdj13nnc1aN%pasde.bcausse.spam@wanadoo.fr,
non seulement table != 0 mais aucune exception bad_alloc est levée.
Il se passe quoi ? Rien ? As-tu fait quelque chose avec ce qui est
« alloué » ?
comprends pas :-(
Pourquoi tiens-tu tant à utiliser trop de mémoire ? :-)
D'abord, renvoyer 0 n'est pas une option avec un compilateur
conforme (mais c'était encore le cas avec VC6 par exemple,
en principe en tout cas).
Par ailleurs, selon les plate-formes, il est tout à fait possible
de ne jamais réussir à obtenir un bad_alloc... malheureusement.
Ce n'est pas le compilateur C++ qui a le contrôle de l'allocation
mémoire, il ne fait que demander l'espace au système d'exploitation.
Si le SE dit « OK, voici l'adresse de la mémoire », mais qu'il ne
l'alloue pas vraiment tant qu'on n'y accède pas, alors C++ ne peut
générer un bad_alloc. Ce comportement est pourtant celui de Linux
(par défaut : il semble qu'il soit possible de le modifier).
Sur d'autres SE, avant de pouvoir dire qu'il n'y a plus de mémoire
disponible (n'oublions pas la mémoire virtuelle) il se passera
beaucoup de choses (swapping et/ou thrashing !) et il est fort
possible que le SE ou un programme plus important que le tien
plante et bloque tout...
Tu n'as pas dit sur quelle plate-forme tu travailles, alors
peut-être que rien de ce que je viens de dire ne s'applique,
mais je crois qu'essayer d'avoir un bad_alloc manuellement
n'est probablement pas très utile... (il y a des programmes
fait exprès pour ce genre de tests)
--
Michel Michaud mm@gdzid.com
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/
non seulement table != 0 mais aucune exception bad_alloc est levée.
Il se passe quoi ? Rien ? As-tu fait quelque chose avec ce qui est « alloué » ?
comprends pas :-(
Pourquoi tiens-tu tant à utiliser trop de mémoire ? :-)
D'abord, renvoyer 0 n'est pas une option avec un compilateur conforme (mais c'était encore le cas avec VC6 par exemple, en principe en tout cas).
Par ailleurs, selon les plate-formes, il est tout à fait possible de ne jamais réussir à obtenir un bad_alloc... malheureusement. Ce n'est pas le compilateur C++ qui a le contrôle de l'allocation mémoire, il ne fait que demander l'espace au système d'exploitation. Si le SE dit « OK, voici l'adresse de la mémoire », mais qu'il ne l'alloue pas vraiment tant qu'on n'y accède pas, alors C++ ne peut générer un bad_alloc. Ce comportement est pourtant celui de Linux (par défaut : il semble qu'il soit possible de le modifier).
Sur d'autres SE, avant de pouvoir dire qu'il n'y a plus de mémoire disponible (n'oublions pas la mémoire virtuelle) il se passera beaucoup de choses (swapping et/ou thrashing !) et il est fort possible que le SE ou un programme plus important que le tien plante et bloque tout...
Tu n'as pas dit sur quelle plate-forme tu travailles, alors peut-être que rien de ce que je viens de dire ne s'applique, mais je crois qu'essayer d'avoir un bad_alloc manuellement n'est probablement pas très utile... (il y a des programmes fait exprès pour ce genre de tests)
-- Michel Michaud http://www.gdzid.com FAQ de fr.comp.lang.c++ : http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/
pasde.bcausse.spam
Michel Michaud wrote:
Tu n'as pas dit sur quelle plate-forme tu travailles, alors peut-être que rien de ce que je viens de dire ne s'applique, mais je crois qu'essayer d'avoir un bad_alloc manuellement n'est probablement pas très utile... (il y a des programmes fait exprès pour ce genre de tests)
je voulais tester le declenchement d'une exception bad_alloc, suite a l'echec de new.
ca fonctionne correctement :-) c'est mon code reel (pas celui du post qui est epuré) qui etait buggé (une variable masquée)
merci pour ton temps
ca progresse doucement :-) -- Bruno Causse http://perso.wanadoo.fr/othello
Michel Michaud <mm@gdzid.com> wrote:
Tu n'as pas dit sur quelle plate-forme tu travailles, alors
peut-être que rien de ce que je viens de dire ne s'applique,
mais je crois qu'essayer d'avoir un bad_alloc manuellement
n'est probablement pas très utile... (il y a des programmes
fait exprès pour ce genre de tests)
je voulais tester le declenchement d'une exception bad_alloc,
suite a l'echec de new.
ca fonctionne correctement :-) c'est mon code reel (pas celui du post
qui est epuré) qui etait buggé (une variable masquée)
merci pour ton temps
ca progresse doucement :-)
--
Bruno Causse
http://perso.wanadoo.fr/othello
Tu n'as pas dit sur quelle plate-forme tu travailles, alors peut-être que rien de ce que je viens de dire ne s'applique, mais je crois qu'essayer d'avoir un bad_alloc manuellement n'est probablement pas très utile... (il y a des programmes fait exprès pour ce genre de tests)
je voulais tester le declenchement d'une exception bad_alloc, suite a l'echec de new.
ca fonctionne correctement :-) c'est mon code reel (pas celui du post qui est epuré) qui etait buggé (une variable masquée)
merci pour ton temps
ca progresse doucement :-) -- Bruno Causse http://perso.wanadoo.fr/othello
Fabien LE LEZ
On Wed, 25 May 2005 23:27:30 +0200, (Bruno Causse):
je voulais tester le declenchement d'une exception bad_alloc, suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ? Généralement, ça veut dire que le système est dans un tel état que le programme ne peut de toutes façons pas continuer.
On Wed, 25 May 2005 23:27:30 +0200, pasde.bcausse.spam@wanadoo.fr
(Bruno Causse):
je voulais tester le declenchement d'une exception bad_alloc,
suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ?
Généralement, ça veut dire que le système est dans un tel état que le
programme ne peut de toutes façons pas continuer.
On Wed, 25 May 2005 23:27:30 +0200, (Bruno Causse):
je voulais tester le declenchement d'une exception bad_alloc, suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ? Généralement, ça veut dire que le système est dans un tel état que le programme ne peut de toutes façons pas continuer.
Jean-Marc Bourguet
(Bruno Causse) writes:
const unsigned long capacity = 1<<31; //2147483648
C'est peut-etre un peu trop... un probleme possible est que
capacite*sizeof(RX_B)
est fait sans verifier le depassement de capacite (::operator new ne voit qu'un size_t, donc ne peut pas le detecter, il faut que ce soit fait ailleurs) qui resulte en une taille possible.
A+
-- 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
const unsigned long capacity = 1<<31; //2147483648
C'est peut-etre un peu trop... un probleme possible est que
capacite*sizeof(RX_B)
est fait sans verifier le depassement de capacite (::operator new ne
voit qu'un size_t, donc ne peut pas le detecter, il faut que ce soit
fait ailleurs) qui resulte en une taille possible.
A+
--
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
const unsigned long capacity = 1<<31; //2147483648
C'est peut-etre un peu trop... un probleme possible est que
capacite*sizeof(RX_B)
est fait sans verifier le depassement de capacite (::operator new ne voit qu'un size_t, donc ne peut pas le detecter, il faut que ce soit fait ailleurs) qui resulte en une taille possible.
A+
-- 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
Jean-Marc Bourguet
Fabien LE LEZ writes:
On Wed, 25 May 2005 23:27:30 +0200, (Bruno Causse):
je voulais tester le declenchement d'une exception bad_alloc, suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ? Généralement, ça veut dire que le système est dans un tel état que le programme ne peut de toutes façons pas continuer.
Je ne vois pas en quoi bad_alloc est different des autres exceptions. Tout depend ou tu recuperes l'exception et de ce que tu fais apres. bad_alloc est certainement recuperable sans probleme dans un systeme ou il y a des transactions.
Exemple imaginaire: un compilateur qui a des passes d'optimisation pouvant prendre beaucoup de memoire. Certaines de ces passes peuvent etre try { hugeCodeRepresentation = transformToHR(currentCode) newCode = generate_alternative(hugeCodeRepresentation); currentCode = transformToSR(newCode); } catch (std::bad_alloc) { }
Evidemment, les problemes pratiques que posent un compilateur qui genere du code different suivant la memoire disponible font que ce n'est peut-etre pas une tres bonne idee, mais sur un systeme faisant de l'optimisation au link, il n'y a peut-etre guere de choix.
A+
-- 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
Fabien LE LEZ <gramster@gramster.com> writes:
On Wed, 25 May 2005 23:27:30 +0200, pasde.bcausse.spam@wanadoo.fr
(Bruno Causse):
je voulais tester le declenchement d'une exception bad_alloc,
suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ?
Généralement, ça veut dire que le système est dans un tel état que le
programme ne peut de toutes façons pas continuer.
Je ne vois pas en quoi bad_alloc est different des autres exceptions.
Tout depend ou tu recuperes l'exception et de ce que tu fais apres.
bad_alloc est certainement recuperable sans probleme dans un systeme
ou il y a des transactions.
Exemple imaginaire: un compilateur qui a des passes d'optimisation
pouvant prendre beaucoup de memoire. Certaines de ces passes peuvent
etre
try {
hugeCodeRepresentation = transformToHR(currentCode)
newCode = generate_alternative(hugeCodeRepresentation);
currentCode = transformToSR(newCode);
} catch (std::bad_alloc) {
}
Evidemment, les problemes pratiques que posent un compilateur qui
genere du code different suivant la memoire disponible font que ce
n'est peut-etre pas une tres bonne idee, mais sur un systeme faisant
de l'optimisation au link, il n'y a peut-etre guere de choix.
A+
--
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
On Wed, 25 May 2005 23:27:30 +0200, (Bruno Causse):
je voulais tester le declenchement d'une exception bad_alloc, suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ? Généralement, ça veut dire que le système est dans un tel état que le programme ne peut de toutes façons pas continuer.
Je ne vois pas en quoi bad_alloc est different des autres exceptions. Tout depend ou tu recuperes l'exception et de ce que tu fais apres. bad_alloc est certainement recuperable sans probleme dans un systeme ou il y a des transactions.
Exemple imaginaire: un compilateur qui a des passes d'optimisation pouvant prendre beaucoup de memoire. Certaines de ces passes peuvent etre try { hugeCodeRepresentation = transformToHR(currentCode) newCode = generate_alternative(hugeCodeRepresentation); currentCode = transformToSR(newCode); } catch (std::bad_alloc) { }
Evidemment, les problemes pratiques que posent un compilateur qui genere du code different suivant la memoire disponible font que ce n'est peut-etre pas une tres bonne idee, mais sur un systeme faisant de l'optimisation au link, il n'y a peut-etre guere de choix.
A+
-- 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
kanze
Fabien LE LEZ wrote:
On Wed, 25 May 2005 23:27:30 +0200, (Bruno Causse):
je voulais tester le declenchement d'une exception bad_alloc, suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ?
Est-ce qu'il y a des cas où on peut se permettre de ne pas l'attraper ? En général, après l'avoir attrapé, on sort proprement du programme. Mais ce « proprement » n'est pas sans intérêt -- si on ne l'attrape pas, ce n'est pas spécifié si la pile a été déballée et les destructeurs appelés ; en ne l'attrapant pas, on risque de ne pas libérer certaines ressources (comme des fichiers temporaires).
Dans les petits programmes que j'écris comme ça, je ne l'attrape pas, mais dans toutes les applications robustes, la fonction main n'est qu'un bloc try, avec un catch( ... ) à la fin, précisement pour cette raison.
Généralement, ça veut dire que le système est dans un tel état que le programme ne peut de toutes façons pas continuer.
Généralement, je suis d'accord avec toi. Généralement, parce qu'il existe aussi des exceptions.
-- 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
Fabien LE LEZ wrote:
On Wed, 25 May 2005 23:27:30 +0200, pasde.bcausse.spam@wanadoo.fr
(Bruno Causse):
je voulais tester le declenchement d'une exception bad_alloc,
suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ?
Est-ce qu'il y a des cas où on peut se permettre de ne pas
l'attraper ? En général, après l'avoir attrapé, on sort
proprement du programme. Mais ce « proprement » n'est pas sans
intérêt -- si on ne l'attrape pas, ce n'est pas spécifié si la
pile a été déballée et les destructeurs appelés ; en ne
l'attrapant pas, on risque de ne pas libérer certaines
ressources (comme des fichiers temporaires).
Dans les petits programmes que j'écris comme ça, je ne l'attrape
pas, mais dans toutes les applications robustes, la fonction
main n'est qu'un bloc try, avec un catch( ... ) à la fin,
précisement pour cette raison.
Généralement, ça veut dire que le système est dans un tel état
que le programme ne peut de toutes façons pas continuer.
Généralement, je suis d'accord avec toi. Généralement, parce
qu'il existe aussi des exceptions.
--
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
On Wed, 25 May 2005 23:27:30 +0200, (Bruno Causse):
je voulais tester le declenchement d'une exception bad_alloc, suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ?
Est-ce qu'il y a des cas où on peut se permettre de ne pas l'attraper ? En général, après l'avoir attrapé, on sort proprement du programme. Mais ce « proprement » n'est pas sans intérêt -- si on ne l'attrape pas, ce n'est pas spécifié si la pile a été déballée et les destructeurs appelés ; en ne l'attrapant pas, on risque de ne pas libérer certaines ressources (comme des fichiers temporaires).
Dans les petits programmes que j'écris comme ça, je ne l'attrape pas, mais dans toutes les applications robustes, la fonction main n'est qu'un bloc try, avec un catch( ... ) à la fin, précisement pour cette raison.
Généralement, ça veut dire que le système est dans un tel état que le programme ne peut de toutes façons pas continuer.
Généralement, je suis d'accord avec toi. Généralement, parce qu'il existe aussi des exceptions.
-- 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
kanze
Jean-Marc Bourguet wrote:
Fabien LE LEZ writes:
On Wed, 25 May 2005 23:27:30 +0200, (Bruno Causse):
je voulais tester le declenchement d'une exception bad_alloc, suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ? Généralement, ça veut dire que le système est dans un tel état que le programme ne peut de toutes façons pas continuer.
Je ne vois pas en quoi bad_alloc est different des autres exceptions.
Parce que le système d'exploitation y a son mot à dire, peut-être ?
Je ne sais pas ce auquel pensait Fabien, mais c'est sur que sur un Linux, dans sa configuration par défaut d'il y a plusieurs années, au moins, ce n'était pas la peine d'attraper un bad_alloc, parce que tu ne le voyais pas. J'ai aussi fait des essaies sous Windows NT (aussi, il y a assez longtemps) : dans la configuration qu'on m'a fourni, avant de signaler un échec à l'allocation, le système présentait une pop-up, qu'il fallait acquitter. Pas la peine de chercher à attraper l'erreur là non plus, dans une application serveur (qui tournait sur un système où il n'y avait personne devant l'écran).
Ceci dit, dans un programme robuste, je préfère attraper toutes les exceptions, dans exception, pour des raisons que j'ai expliqué dans un autre posting.
Tout depend ou tu recuperes l'exception et de ce que tu fais apres. bad_alloc est certainement recuperable sans probleme dans un systeme ou il y a des transactions.
Peut-être, mais ce n'est pas sûr. Tout dépend de pourquoi tu as eu le bad_alloc. Mes serveurs tournent sur des plateformes dédiées -- c-à-d sans autres applications qui tournent en même temps. On gère la mémoire, y compris dans les transactions ; on sait combien il en faut, et on dimensionne la machine en conséquence. Du coup, bad_alloc est synonyme à une fuite de mémoire. Et on ne peut pas le récupérer et continuer.
Évidemment, il existe des serveurs où les transactions peuvent avoir une complexité arbitraire -- tout serveur LAPD, par exemple. Là, il y a bien un sens d'attraper bad_alloc en haut de la transaction, de renvoyer un message d'erreur (« insufficient resources » est un cas d'erreur prévu), et de continuer. Sauf, évidemment, pour faire bien, il faudrait aussi faire pareil en cas de débordement de la pile:-).
Exemple imaginaire: un compilateur qui a des passes d'optimisation pouvant prendre beaucoup de memoire. Certaines de ces passes peuvent etre try { hugeCodeRepresentation = transformToHR(currentCode) newCode = generate_alternative(hugeCodeRepresentation); currentCode = transformToSR(newCode); } catch (std::bad_alloc) { }
Evidemment, les problemes pratiques que posent un compilateur qui genere du code different suivant la memoire disponible font que ce n'est peut-etre pas une tres bonne idee, mais sur un systeme faisant de l'optimisation au link, il n'y a peut-etre guere de choix.
Selon le cas, on pourrait aussi considérer l'utilisation de new (nothrow) pour ce genre de problème. Avec des pointeurs intelligent, qui permet de spiller sur disque, si l'utilisateur le démande.
-- 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
Jean-Marc Bourguet wrote:
Fabien LE LEZ <gramster@gramster.com> writes:
On Wed, 25 May 2005 23:27:30 +0200,
pasde.bcausse.spam@wanadoo.fr (Bruno Causse):
je voulais tester le declenchement d'une exception
bad_alloc, suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ?
Généralement, ça veut dire que le système est dans un tel
état que le programme ne peut de toutes façons pas
continuer.
Je ne vois pas en quoi bad_alloc est different des autres
exceptions.
Parce que le système d'exploitation y a son mot à dire,
peut-être ?
Je ne sais pas ce auquel pensait Fabien, mais c'est sur que sur
un Linux, dans sa configuration par défaut d'il y a plusieurs
années, au moins, ce n'était pas la peine d'attraper un
bad_alloc, parce que tu ne le voyais pas. J'ai aussi fait des
essaies sous Windows NT (aussi, il y a assez longtemps) : dans
la configuration qu'on m'a fourni, avant de signaler un échec à
l'allocation, le système présentait une pop-up, qu'il fallait
acquitter. Pas la peine de chercher à attraper l'erreur là non
plus, dans une application serveur (qui tournait sur un système
où il n'y avait personne devant l'écran).
Ceci dit, dans un programme robuste, je préfère attraper toutes
les exceptions, dans exception, pour des raisons que j'ai
expliqué dans un autre posting.
Tout depend ou tu recuperes l'exception et de ce que tu fais
apres. bad_alloc est certainement recuperable sans probleme
dans un systeme ou il y a des transactions.
Peut-être, mais ce n'est pas sûr. Tout dépend de pourquoi tu as
eu le bad_alloc. Mes serveurs tournent sur des plateformes
dédiées -- c-à-d sans autres applications qui tournent en même
temps. On gère la mémoire, y compris dans les transactions ; on
sait combien il en faut, et on dimensionne la machine en
conséquence. Du coup, bad_alloc est synonyme à une fuite de
mémoire. Et on ne peut pas le récupérer et continuer.
Évidemment, il existe des serveurs où les transactions peuvent
avoir une complexité arbitraire -- tout serveur LAPD, par
exemple. Là, il y a bien un sens d'attraper bad_alloc en haut de
la transaction, de renvoyer un message d'erreur (« insufficient
resources » est un cas d'erreur prévu), et de continuer. Sauf,
évidemment, pour faire bien, il faudrait aussi faire pareil en
cas de débordement de la pile:-).
Exemple imaginaire: un compilateur qui a des passes
d'optimisation pouvant prendre beaucoup de memoire. Certaines
de ces passes peuvent etre
try {
hugeCodeRepresentation = transformToHR(currentCode)
newCode = generate_alternative(hugeCodeRepresentation);
currentCode = transformToSR(newCode);
} catch (std::bad_alloc) {
}
Evidemment, les problemes pratiques que posent un compilateur
qui genere du code different suivant la memoire disponible
font que ce n'est peut-etre pas une tres bonne idee, mais sur
un systeme faisant de l'optimisation au link, il n'y a
peut-etre guere de choix.
Selon le cas, on pourrait aussi considérer l'utilisation de new
(nothrow) pour ce genre de problème. Avec des pointeurs
intelligent, qui permet de spiller sur disque, si l'utilisateur
le démande.
--
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
On Wed, 25 May 2005 23:27:30 +0200, (Bruno Causse):
je voulais tester le declenchement d'une exception bad_alloc, suite a l'echec de new.
Y a-t-il des cas où on doit vraiment attraper bad_alloc ? Généralement, ça veut dire que le système est dans un tel état que le programme ne peut de toutes façons pas continuer.
Je ne vois pas en quoi bad_alloc est different des autres exceptions.
Parce que le système d'exploitation y a son mot à dire, peut-être ?
Je ne sais pas ce auquel pensait Fabien, mais c'est sur que sur un Linux, dans sa configuration par défaut d'il y a plusieurs années, au moins, ce n'était pas la peine d'attraper un bad_alloc, parce que tu ne le voyais pas. J'ai aussi fait des essaies sous Windows NT (aussi, il y a assez longtemps) : dans la configuration qu'on m'a fourni, avant de signaler un échec à l'allocation, le système présentait une pop-up, qu'il fallait acquitter. Pas la peine de chercher à attraper l'erreur là non plus, dans une application serveur (qui tournait sur un système où il n'y avait personne devant l'écran).
Ceci dit, dans un programme robuste, je préfère attraper toutes les exceptions, dans exception, pour des raisons que j'ai expliqué dans un autre posting.
Tout depend ou tu recuperes l'exception et de ce que tu fais apres. bad_alloc est certainement recuperable sans probleme dans un systeme ou il y a des transactions.
Peut-être, mais ce n'est pas sûr. Tout dépend de pourquoi tu as eu le bad_alloc. Mes serveurs tournent sur des plateformes dédiées -- c-à-d sans autres applications qui tournent en même temps. On gère la mémoire, y compris dans les transactions ; on sait combien il en faut, et on dimensionne la machine en conséquence. Du coup, bad_alloc est synonyme à une fuite de mémoire. Et on ne peut pas le récupérer et continuer.
Évidemment, il existe des serveurs où les transactions peuvent avoir une complexité arbitraire -- tout serveur LAPD, par exemple. Là, il y a bien un sens d'attraper bad_alloc en haut de la transaction, de renvoyer un message d'erreur (« insufficient resources » est un cas d'erreur prévu), et de continuer. Sauf, évidemment, pour faire bien, il faudrait aussi faire pareil en cas de débordement de la pile:-).
Exemple imaginaire: un compilateur qui a des passes d'optimisation pouvant prendre beaucoup de memoire. Certaines de ces passes peuvent etre try { hugeCodeRepresentation = transformToHR(currentCode) newCode = generate_alternative(hugeCodeRepresentation); currentCode = transformToSR(newCode); } catch (std::bad_alloc) { }
Evidemment, les problemes pratiques que posent un compilateur qui genere du code different suivant la memoire disponible font que ce n'est peut-etre pas une tres bonne idee, mais sur un systeme faisant de l'optimisation au link, il n'y a peut-etre guere de choix.
Selon le cas, on pourrait aussi considérer l'utilisation de new (nothrow) pour ce genre de problème. Avec des pointeurs intelligent, qui permet de spiller sur disque, si l'utilisateur le démande.
-- 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
kanze
Jean-Marc Bourguet wrote:
(Bruno Causse) writes:
const unsigned long capacity = 1<<31; //2147483648
C'est peut-etre un peu trop... un probleme possible est que
capacite*sizeof(RX_B)
est fait sans verifier le depassement de capacite (::operator new ne voit qu'un size_t, donc ne peut pas le detecter, il faut que ce soit fait ailleurs) qui resulte en une taille possible.
Est-ce qu'il y a eu un DR là-dessus, avec une décision du comité@? Parce que la norme est claire : quelque soit le nombre d'éléments que tu passes à l'expression new, ou bien, elle les alloue, ou bien, elle lève l'exception bad_alloc.
Mais évidemment, aucune implémentation ne le fait. Et ça pose des problèmes à l'implémentation -- parce que les tests de débordement, il faut que ce soit avant l'appel de la fonction operator new qu'ils aient lieu, mais qu'en cas de débordement, il faut que le comportement soit exactement celui de la fonction operator new. Y compris si la fonction operator new a été remplacée par l'utilisateur.
De toute façon, si son problème, c'est simplement de tester le comportement de son code en cas d'épuisement de la mémoire, la solution la plus évident, c'est de remplacer la fonction operator new avec quelque chose comme :
void* operator new( size_t n ) { if ( triggerCount > 0 ) { -- triggerCount ; if ( triggerCount == 0 ) { throw std::bad_alloc ; } } void* p = malloc( n ) ; if ( p == NULL ) { throw std::bad_alloc ; // Ou carrément avorter ... } return p ; }
-- 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
const unsigned long capacity = 1<<31; //2147483648
C'est peut-etre un peu trop... un probleme possible est que
capacite*sizeof(RX_B)
est fait sans verifier le depassement de capacite (::operator
new ne voit qu'un size_t, donc ne peut pas le detecter, il
faut que ce soit fait ailleurs) qui resulte en une taille
possible.
Est-ce qu'il y a eu un DR là-dessus, avec une décision du
comité@? Parce que la norme est claire : quelque soit le nombre
d'éléments que tu passes à l'expression new, ou bien, elle les
alloue, ou bien, elle lève l'exception bad_alloc.
Mais évidemment, aucune implémentation ne le fait. Et ça pose
des problèmes à l'implémentation -- parce que les tests de
débordement, il faut que ce soit avant l'appel de la fonction
operator new qu'ils aient lieu, mais qu'en cas de débordement,
il faut que le comportement soit exactement celui de la fonction
operator new. Y compris si la fonction operator new a été
remplacée par l'utilisateur.
De toute façon, si son problème, c'est simplement de tester le
comportement de son code en cas d'épuisement de la mémoire, la
solution la plus évident, c'est de remplacer la fonction
operator new avec quelque chose comme :
void*
operator new( size_t n )
{
if ( triggerCount > 0 ) {
-- triggerCount ;
if ( triggerCount == 0 ) {
throw std::bad_alloc ;
}
}
void* p = malloc( n ) ;
if ( p == NULL ) {
throw std::bad_alloc ;
// Ou carrément avorter ...
}
return p ;
}
--
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
const unsigned long capacity = 1<<31; //2147483648
C'est peut-etre un peu trop... un probleme possible est que
capacite*sizeof(RX_B)
est fait sans verifier le depassement de capacite (::operator new ne voit qu'un size_t, donc ne peut pas le detecter, il faut que ce soit fait ailleurs) qui resulte en une taille possible.
Est-ce qu'il y a eu un DR là-dessus, avec une décision du comité@? Parce que la norme est claire : quelque soit le nombre d'éléments que tu passes à l'expression new, ou bien, elle les alloue, ou bien, elle lève l'exception bad_alloc.
Mais évidemment, aucune implémentation ne le fait. Et ça pose des problèmes à l'implémentation -- parce que les tests de débordement, il faut que ce soit avant l'appel de la fonction operator new qu'ils aient lieu, mais qu'en cas de débordement, il faut que le comportement soit exactement celui de la fonction operator new. Y compris si la fonction operator new a été remplacée par l'utilisateur.
De toute façon, si son problème, c'est simplement de tester le comportement de son code en cas d'épuisement de la mémoire, la solution la plus évident, c'est de remplacer la fonction operator new avec quelque chose comme :
void* operator new( size_t n ) { if ( triggerCount > 0 ) { -- triggerCount ; if ( triggerCount == 0 ) { throw std::bad_alloc ; } } void* p = malloc( n ) ; if ( p == NULL ) { throw std::bad_alloc ; // Ou carrément avorter ... } return p ; }
-- 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