Je parlais à un collègue l'autre jour sur la façon dont vous pouvez fuir une chaîne à Delphes si vous gâchez vraiment les choses. Par défaut, les chaînes sont comptées et allouées automatiquement, elles fonctionnent généralement sans aucune pensée - aucun besoin d'allocation manuelle, de calculs de taille ou de gestion de la mémoire. p>
Mais je me souviens de lire une fois qu'il existe un moyen de fuir une chaîne directement (sans l'inclure dans un objet qui se fuit). Il semble que cela ait eu quelque chose à voir avec la transmission d'une chaîne par référence puis l'accédant d'une plus grande portée de la routine à laquelle elle a été transmise. Oui, je sais que c'est vague, c'est pourquoi je pose la question ici. p>
5 Réponses :
Je ne connais pas la question dans votre deuxième paragraphe, mais j'ai été mordule une fois par des cordes qui ont fui dans un record. P>
Si vous appelez fillchar () em> sur un enregistrement contenant des chaînes, vous écrasez le décompte Ref et l'adresse de la mémoire allouée de manière dynamique avec des zéros. Sauf si la chaîne est vide, cela fuit la mémoire. Le chemin autour de cela est d'appeler finaliser () em> sur l'enregistrement avant d'effacer la mémoire qu'il occupe. P>
Malheureusement, appeler finaliser () em> Lorsqu'il n'y a pas de membres d'enregistrement qui nécessitent finaliser des causes un indice de compilateur. Cela m'est arrivé que j'ai commenté l'appel finaliser () em> pour faire taire l'indice, mais plus tard, lorsque j'ai ajouté un membre de chaîne à l'enregistrement, j'ai raté l'appel, donc une fuite a été introduite. Heureusement, j'utilise généralement le gestionnaire de mémoire FastMM dans le réglage le plus verbeux et le plus paranoïaque dans le mode de débogage, de sorte que la fuite ne soit pas passée inaperçue. P>
Le compilateur indique n'est probablement pas une si bonne chose, omettant silencieusement l'appel finaliser () em> s'il n'est pas nécessaire serait beaucoup mieux IMHO. P>
> omettre silencieusement l'appel finalize () s'il n'est pas nécessaire serait beaucoup mieux IMHO +1
Savez-vous si des cordes courtes touchées par cela?
@Jamesb: Non, la chaîne courte n'est pas affectée par ceci, car elles ne sont pas comptées et ne sont pas consistées à des pointeurs sur des morceaux de mémoire qui pourraient être perdues. Les chaînes courtes sont constituées d'un octet de longueur unique et des données de caractères, donc les remplir avec 0 code> s définit la longueur sur
0 code> et définit tous les éléments sur
# 0 < / code>.
Je pensais que c'était le cas ... Tout au long de notre code avec des disques avec des cordes courtes (vraiment agaçant que les données ne soient pas tronquées parce qu'elles ne sont pas assez grandes) et je me suis toujours demandé pourquoi ... je parierai que c'est le raison.
Non, je ne pense pas qu'une telle chose puisse arriver. Il est possible pour une variable de chaîne d'obtenir une valeur que vous ne vous attendiez pas, mais cela ne fuit pas la mémoire. Considérez ceci:
New(Rec); Rec^.field := IntToStr(4); Dispose(Rec);
AFAICS L'exemple global fonctionne pour tout type de variable, ce n'est probablement pas ce que Jim est après.
Ah, tu as raison. Mais comme une chaîne, il peut i> causer des problèmes supplémentaires, comme je suis sur le point de démontrer quand je modifierai cette réponse.
En réalité, une chaîne de transmission en tant que const ou non constitue le nombre de comptes de référence dans Delphi 2007 et 2009. Il y avait une affaire qui causait une violation d'accès lorsque la chaîne est transmise en tant que const. Voici le problème qu'un
Cela ressemble un peu comme je pensais, mais ce n'est pas en 2009, ce que je crois, c'est ce que tu disais.
Il n'existe pas d'AV car à Delphi 2009, le "const" perd sa fonctionnalité si $ stringchecks sont sur.
Je pense Ce aurait pu être similaire à ce que je pensais. C'est l'inverse d'une fuite de cordes, une chaîne qui est collectée tôt:
Vous avez un pointeur sur un objet sur la pile qui est sorti de la portée. Qu'attendez-vous??? Si la chaîne est nettoyée ou non, cela risque de souffler.
Loren, vous Attendez-vous I> Tout fonctionner exactement comme vous le vouliez, quel que soit le code réel que vous avez écrit! Le compilateur est psychique de nos jours, n'est-ce pas?
Dois être d'accord avec Loren ici. La seconde que vous appelez le symbole @, tous les paris sont éteints. Vous enchérissez le compilateur un adieu poli sur tous les mécanismes de sécurité et de comptage de type de type de type et de référence et de prendre la mémoire brute entre vos propres mains.
Oui, celui-ci est assez évident. Je vais continuer à chercher, mais j'aurais peut-être oublié que je me suis rappelé ou que cela a été corrigé.
Une autre façon de fuir une chaîne est de le déclarer comme une variable de filetage. Voir Ma question pour plus de détails. Et pour la solution, voir la solution sur la façon de le ranger . P>