Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Probleme de redefinition de new/delete

18 réponses
Avatar
Dominique Vaufreydaz
Bonjour,

je veux faire un outil de suivi des allocation desallocation...
Je me suis dit, nickel, je redéfinis new, new[] et ses pendants
en delete. Pas de soucis. Sauf si la personne inclu un fichier
Windows en mode debug qui fait sa propre redéfinition
de new (pour pouvoir aussi faire sa propre gestion de fuite memoire).

Quelqu'un voit-il un moyen pour s'en sortir ? Je sais je peux
compiler en Release (donc sans utiliser les artefacts Winwin
pour ca et ca marche), mais l'idée générale c'est que c'est
pénible de ne pas avoir les 2 en meme temps...

Merci de vos lumieres. Doms.

8 réponses

1 2
Avatar
James Kanze
Dominique Vaufreydaz wrote:

Je ne vois pas où ça doit faire des problèmes. Le remplacement
s'effectue normalement au moment de l'édition des liens.
(J'utilise regulièrement mon propre operator new de déboggage
avec des programmes compilés avec VC++, sans problèmes. Des
programmes mode console, quand même, mais je ne crois pas que ça
change quelque chose à cet égard.)


Ben en mode debug, donc avec le symbole qui va bien qui est défini
si, y'a probleme. Probleme car je rajoute des parametres a new et donc
je suis oblige de faire un define pour les mettre en place...


Ce n'est donc pas l'operator new normal, mais un « placement
new ». C'est donc autre chose : quand tu appelles new avec les
paramètres, il va appeler le tien, et quand tu l'appelles sans,
celui par défaut.

Dans la pratique, il faut quand même remplacer l'operator new
global aussi, parce que l'operator delete qui serait appelé
serait toujours la version par défaut (sauf dans certains cas
spéciaux où une expression new se termine par une exception). Et
il faut, dans l'operator delete, pouvoir distinguer comment a
été alloué la mémoire, et agir en conséquence.

Les deux en même temps, je ne crois pas que ce soit faisable. Ce
sont en fin de compte des fonctions, tous les deux avec le même
nom (après décoration).


Ben pas vraiment puisque moi j'ajoute mes propres
parametres (permettant entre autre de savoir sur quel
ligne a ete fait le new dans quel fichier) => probleme, je
fais un define car j'ai pas le choix...


Sauf qu'il va bien falloir que tu remplaces l'operator delete
global, parce que pour l'operator delete, tu n'as pas de
possibilité de lui passer des paramètres.

JE vais poster mon header, ca eclairera peut-etre...


La technique est connue. Ce n'est pas la première fois que j'en
entend parler.

Dans l'ensemble, je ne crois pas qu'il soit une bonne idée.
C'est beaucoup mieux de remplacer les operator standard
carrément.

--
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


Avatar
Jean-Marc Bourguet
"James Kanze" writes:

Jean-Marc Bourguet wrote:
"Dominique Vaufreydaz" writes:

void * operator new( size_t size, int line, const char *file );
void * operator new[]( size_t size, int line, const char *file );
void operator delete( void *p );
void operator delete[]( void *p );


Je me demande si ton problème n'est pas que les deux
opérateurs new ((size_t size, int line, const char *file) et
(size_t size)) ne sont pas utilisés et que delete ne
fonctionne bien que pour le premier. Une solution dans ce
cas-là serait de remplacer l'operator new(size_t size) de la
bibliothèque par un qui fonctionne bien avec ton operator
delete. (Et de même pour les version []).


Il y a un problème même plus fondamental. Il a violé
§17.4.3.1.1/2 : « A translation unit that includes a header
shall not contain any macros that define names declared or
defined in that header. Nor shall such a translation unit define
macros for names lexically identical to keywords. » (« new »
est un mot clé.) Il a un comportement complétement indéfini.


J'avais pas compris qu'il s'amusait à faire ça. Et à relire le message
auquel j'ai répondu, ce n'est pas clair qu'il le fait.

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



Avatar
Jean-Marc Bourguet
"James Kanze" writes:

C'est vrai qu'il y a introduire un niveau d'indirection pour le
masquer un peu. Mais il y a bien :

#define OMISCID_NEW new( __LINE__, __FILE__ )

// ...

#define new OMISCID_NEW


Où il est le numéro de mon ophtalmo? Je crois que je dois changer mes
lunettes... :-)

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

Avatar
loufoque
Bonjour,

je veux faire un outil de suivi des allocation desallocation...
Je me suis dit, nickel, je redéfinis new, new[] et ses pendants
en delete.


Utilise plutôt un profiler et un debugger qui feront un bien meilleur
boulot.

Avatar
Dominique Vaufreydaz
Bonjour,

Utilise plutôt un profiler et un debugger qui feront un bien meilleur
boulot.


J'ai Visual Studio 2005 en complet, aucun soucis, mais bon, les gens
qui utilisent ma lib, ne l'ont pas et ne sont pas satisfait de ce qu'ils
trouvent sous Linux. C'est juste un outils peu cher permettant de savoir
ce qui se passe...

Au moins voir si on gere la memoire de maniere cohérente.

Doms.

Avatar
Arnaud Debaene
"Dominique Vaufreydaz" a écrit dans le message de news:


En gros, je redefinis new en lui ajoutant des parametres (vaguement
la ligne et le nom du fichier de l'allocation, ca peut servir). Ca
marche
tant que je n'inclus pas des trucs genre iostream.h ou string.h, ca
pouf
la CRT me jete grave (parcequ'en fait je redeclare mon operateur new
avec un define aussi puisque j'ajoute des parametres non optionnel...


Donc tu fais la même chose que les MFC, à savoir redéfinir new et delete à
grands coups de macros. AMHA c'est une très mauvaise idée, exactement pour
la même raison que c'est une très mauvaise idée dans les MFC.

Je comprends bien l'intérêt premier de la chose, mais il y a trop de cas où
les mots "new" et "delete" sont utilisés dans des contextes particuliers
(que ce soit dans la CRT ou ailleurs) : tu te prépares à avoir des prolèmes
sans fin dès que tu vas compiler ta librairie avec une librairie tierce ou
une autre.

Arnaud

Avatar
James Kanze
Dominique Vaufreydaz wrote:

Oui, à condition que tu ne fais pas d'autres choses qui posent
un problème.


Ok.

Je pense en particulier au delete. Que fais-tu dans Xdelete ?
En supposant que tu veux bien qu'il appelle le destructeur et
qu'il libère la mémoire. Si c'est le but, quelque chose du
genre :
#define Xdelete ...
ne peut faire qu'un delete standard, et il faut que tu
t'arranges pour qu'il soit capable de traiter à la fois les
blocs alloués dans ton Xnew, et les blocs alloués par un new
standard.


Non, faut pas pousser non plus. Je propose un option permettant
de suivre les alloc (meme sous Linux/OSX) donc charge a l'utilisateur
de faire Xnew/Xdelete, de la meme facon qu'on ne mixe pas
new/free et malloc/delete.


Mais la question reste : comment fais-tu pour implémenter le
delete ? Il faut bien appeler le destructeur dans un delete. Et
autant que je sache, il n'y a que deux moyens de le faire : une
expression delete (qui appelle forcement le delete global), ou
un appel explicit du destructeur, qui veut dire que tu connais
le type. Et que tu saches on trouver l'adresse de l'objet
complet, à partir du pointeur qu'on t'a donné. Et de préfèrence,
que tu fasses tout ça en n'évaluant l'expression du pointeur
qu'une seule fois, parce que tu peux être certain qu'il y a des
gens qui vont faire des choses du genre :

delete *iter ++ ;

Dans l'ensemble, je ne saurais pas le faire. Et cependant, je
crois connaître assez bien le C++.

Pas de problème, mais je ne vois toujours pas trop comment ça va
marcher. (Moi, je remplace le new et le delete globaux,
carrément, sans macro. Et ça marche bien.)


Ca je l'ai fait, ca marche nickel mais j'ai pas les lignes
et encore une fois, sous Visual ca se joue, sous gcc, plus
dur. Et puis si Purify annonce fichier/ligne, je vois pas
pourquoi ca servirait pas !


Les versions du Purify dont je me suis servi ont toujours donné
une trace de la pile. Et c'est fort rarement que la première
entrée m'a servi.

Moi, j'effectue une rémontée de la pile, eniviron dix niveaux.
Je sors les adresses en hex, c'est vrai, et non en symbolique.
Mais sous Linux (ou avec binutils, si tu l'as installé), il y a
une commande pour convertir les adresses hex en numéros de
lignes, et de toute façon, ce n'est pas difficile à trouver où
se trouve l'adresse hex une fois qu'on a un map.

--
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


Avatar
Dominique Vaufreydaz
Bonjour,

Mais la question reste : comment fais-tu pour implémenter le
delete ? Il faut bien appeler le destructeur dans un delete. Et
autant que je sache, il n'y a que deux moyens de le faire : une
expression delete (qui appelle forcement le delete global), ou
un appel explicit du destructeur, qui veut dire que tu connais
le type. Et que tu saches on trouver l'adresse de l'objet
complet, à partir du pointeur qu'on t'a donné. Et de préfèrence,
que tu fasses tout ça en n'évaluant l'expression du pointeur
qu'une seule fois, parce que tu peux être certain qu'il y a des
gens qui vont faire des choses du genre :


Bon, je me contente de faire l'affichage des leaks avec
l'adresse, les 20 premiers octets et l'ordre dans lequel
ils ont été

Moi, j'effectue une rémontée de la pile, eniviron dix niveaux.
Je sors les adresses en hex, c'est vrai, et non en symbolique.
Mais sous Linux (ou avec binutils, si tu l'as installé), il y a
une commande pour convertir les adresses hex en numéros de
lignes, et de toute façon, ce n'est pas difficile à trouver où
se trouve l'adresse hex une fois qu'on a un map.


L'idée était de simplifier les choses au maximum pour
des utilisateurs lambda (pas des experts en dev qui pourraient
utiliser toute la batterie pour les aider).

Je vais rester dans l'idée de base et on verra bien si y'a besoin de
mieux, j'indiquerai des outils plus fins que ceux-la...

Merci pour ces precieux conseils. Doms.

1 2