Sur OSX, Valgrind a signalé cette fuite de mémoire. D’où vient-elle?

Sur OSX, Valgrind a signalé cette fuite de mémoire. D’où vient-elle? Le code est compilé avec g ++ en tant que code c ++ (je le fais pour surcharger une fonction).

 == 13088 == 18 octets en 1 blocs sont définitivement perdus dans l'enregistrement de pertes 82 sur 264
 == 13088 == à 0x1F25DC: malloc_zone_malloc (vg_replace_malloc.c: 267)
 == 13088 == par 0xA1AEDA: malloc_set_zone_name (dans /usr/lib/system/libsystem_c.dylib)
 == 13088 == par 0xA1B4A7: _malloc_initialize (dans /usr/lib/system/libsystem_c.dylib)
 == 13088 == par 0xA1B5DD: malloc_good_size (dans /usr/lib/system/libsystem_c.dylib)
 == 13088 == par 0x4EFA6E: __CFSsortingngChangeSizeMultiple (dans /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
 == 13088 == par 0x4F3900: CFSsortingngAppend (dans /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
 == 13088 == par 0x506F91: _convertToURLLepresentation (dans / System / Library / Frameworks / CoreFoundation.framework/Versions/A/CoreFoundation)
 == 13088 == par 0x60F963: _CFURLInit (dans /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
 == 13088 == par 0x4FF268: CFURLCreateWithFileSystemPathRelativeToBase (dans /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
 == 13088 == par 0x4FF8EE: CFURLCreateWithFileSystemPath (dans /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
 == 13088 == par 0x515735: _CFBundleGetMainBundleAlreadyLocked (dans / System / Library / Frameworks / CoreFoundation.framework / Version / A / CoreFoundation)
 == 13088 == par 0x515663: CFBundleGetMainBundle (dans /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
 == 13088 == par 0x539533: cacheBundleInfo (dans /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
 == 13088 == par 0x5394B3: _CFAppVersionCheckLessThan (dans /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
 == 13088 == par 0x56C35B: __CFInitialize (dans /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
 == 13088 == par 0x8FE11243: ImageLoaderMachO :: doImageInit (ImageLoader :: LinkContext const &) (dans / usr / lib / dyld)
 == 13088 == par 0x8FE10CB3: ImageLoaderMachO :: doInitialization (ImageLoader :: LinkContext const &) (dans / usr / lib / dyld)
 == 13088 == par 0x8FE0E21F: ImageLoader :: recursiveInitialization (ImageLoader :: LinkContext const &, unsigned int, ImageLoader :: InitializerTimingList &) (dans / usr / lib / dyld)
 == 13088 == par 0x8FE0E1B5: ImageLoader :: recursiveInitialization (ImageLoader :: LinkContext const &, unsigned int, ImageLoader :: InitializerTimingList &) (dans / usr / lib / dyld)
 == 13088 == par 0x8FE0F1BF: ImageLoader :: runInitializers (ImageLoader :: LinkContext const &, ImageLoader :: InitializerTimingList &) (dans / usr / lib / dyld)
 == 13088 == par 0x8FE03655: dyld :: initializeMainExecutable () (dans / usr / lib / dyld)
 == 13088 == par 0x8FE07EF1: dyld :: _ main (macho_header const *, unsigned long, int, char const **, char const **, char const **) (dans / usr / lib / dyld)
 == 13088 == par 0x8FE012EE: dyldbootstrap :: start (macho_header const *, int, char const **, long, macho_header const *) (dans / usr / lib / dyld)
 == 13088 == par 0x8FE01062: _dyld_start (dans / usr / lib / dyld)
 == 13088 == par 0xFFF: ???

EDIT: aussi, comment pourrais-je libérer cette mémoire?

L’allocation est complètement hors de votre contrôle; la gratuité est également pratiquement impossible pour vous. Cela doit être ajouté à la liste des éléments connus, détectés, enregistrés mais ignorés (le mot “supprimé” est le jargon).

Lorsque je lance un programme sous valgrind 3.7.0 sur MacOS X 10.7.2, je reçois un résumé du type:

==71989== ==71989== HEAP SUMMARY: ==71989== in use at exit: 6,191 bytes in 33 blocks ==71989== total heap usage: 33 allocs, 0 frees, 6,191 bytes allocated ==71989== ==71989== LEAK SUMMARY: ==71989== definitely lost: 0 bytes in 0 blocks ==71989== indirectly lost: 0 bytes in 0 blocks ==71989== possibly lost: 0 bytes in 0 blocks ==71989== still reachable: 6,191 bytes in 33 blocks ==71989== suppressed: 0 bytes in 0 blocks ==71989== Rerun with --leak-check=full to see details of leaked memory ==71989== ==71989== For counts of detected and suppressed errors, rerun with: -v ==71989== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1) 

Cela provient d’un programme qui ne fait pas d’allocation de mémoire explicite – printf() peut déclencher une allocation, mais la plupart de ces octets sont alloués dans des bibliothèques système. Vous avez clairement défini une valeur plus profonde que la normale pour le --num-callers=N ( --num-callers=N ).

Regardez dans le manuel pour savoir comment append correctement un enregistrement de suppression, mais valgrind --help propose:

 --num-callers= show  callers in stack traces [12] --error-limit=no|yes stop showing new errors if too many? [yes] --error-exitcode= exit code to return if errors found [0=disable] --show-below-main=no|yes continue stack traces below main() [no] --suppressions= suppress errors described in  --gen-suppressions=no|yes|all print suppressions for errors? [no] 

Ainsi, vous pouvez demander à valgrind de générer la chaîne de suppression à append à un fichier que vous utiliserez ensuite lors d’exécutions ultérieures.

 Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc 

Cela ressemble plus à une des bibliothèques que vous utilisez. Si c’est le cas, assurez-vous d’utiliser correctement l’API de la bibliothèque, mais sachez qu’une bibliothèque alloue parfois des ressources globales, lorsqu’elle est initialisée par exemple, ce qu’elle ne fait pas. pas libre jusqu’à la fin du programme.

Par exemple, considérons cette situation:

 void init_lib(){ static char *buf=NULL; if (buf==NULL) { buf = malloc(18); } ..... } 

Comment la bibliothèque peut-elle libérer ce tampon avant de quitter? il ne le peut pas jusqu’à ce que le programme se ferme et que sa mémoire soit récupérée par le système d’exploitation.

Voir les pièges communs ici

Edit: techniquement, dans l’exemple ci-dessus, buf peut être libéré comme suggéré par l’un des commentaires ci-dessous, mais de nombreuses bibliothèques ne s’en donnent pas la peine, car buf sera utilisé pendant la durée du programme et la mémoire récupérée. lorsque le programme se ferme, valgrind le signale comme une fuite de mémoire.

Sous OS X, vous devez exécuter valgrind avec –dsymutil = yes pour obtenir plus d’informations utiles sur l’emplacement de la fuite.

Je ne sais pas quelle version d’osx vous utilisez. Mais sur la version en cours, Valgrind signale que ces erreurs sont ignorables.