Valgrind légitime, par exemple, octets «éventuellement perdus»

J’ai vu que valgrind classe les memory leaks dans:

  • définitivement perdu
  • indirectement perdu
  • peut-être perdu
  • toujours accessible
  • supprimé

Je viens de réparer une fuite où le “éventuellement perdu” était le principal problème.

La documentation indique : ” éventuellement perdu signifie que votre programme perd de la mémoire, à moins que vous ne fassiez des choses inhabituelles avec des pointeurs qui pourraient les amener à pointer au milieu d’un bloc alloué; voir le manuel d’utilisation pour connaître les causes possibles”

Puis-je connaître un exemple de ” faire des choses inhabituelles avec des pointeurs qui pourraient les amener à pointer au milieu d’un bloc atsortingbué “?

Je veux dire un exemple où “éventuellement perdu” peut être ignoré bien que cela soit rapporté par valgrind. Un exemple dans lequel l’utilisation de pointeurs provoque la plainte de valgrind mais en même temps l’utilisation de ces pointeurs est en quelque sorte légitime.

Je vous remercie

Quelques exemples de documentation figurant dans différentes bibliothèques ayant leurs propres allocateurs et pour lesquels la mémoire renvoyée n’est pas directement le pointeur renvoyé par l’allocateur du système d’exploitation sous-jacent (malloc / sbrk), mais un pointeur après un décalage. Prenons, par exemple, un allocateur qui a obtenu de la mémoire supplémentaire et des méta-informations stockées (par exemple, des informations de type pour un garbage collector …). Le processus d’allocation et de désallocation serait semblable à:

void* allocate( size_t size ) { metainfo_t *m = (metainfo_t*) malloc( size + sizeof(metainfo) ); m->data = some_value; return (void*)(m+1); // [1] } void deallocate( void* p ) { metainfo_t *m = ((metainfo_t*)p) - 1; // use data } void * memory = allocate(10); 

Lorsque valgrind suit la mémoire, il se souvient du pointeur d’origine renvoyé par malloc , et ce pointeur n’est stocké nulle part dans le programme. Mais cela ne signifie pas que la mémoire a été perdue, cela signifie simplement que le pointeur n’est pas directement disponible dans le programme. En particulier, la memory contient toujours le pointeur renvoyé, et deallocate peut être appelé pour le libérer, mais valgrind ne voit pas le pointeur renvoyé d’origine à l’emplacement (char*)memory - sizeof(metadata_t) nulle part dans le programme et le signale.

 char *p = malloc(100); if (p != 0) { p += 50; /* at this point, no pointer points to the start of the allocated memory */ /* however, it is still accessible */ for (int i = -50; i != 50; i++) p[i] = 1; free (p - 50); } 
 char *p = malloc(100); if (p != 0) { p += 50; /* at this point, no pointer points to the start of the allocated memory */ /* however, it is still accessible */ for (int i = -50; i != 50; i++) p[i] = 1; free (p - 50); } 

Comme cela semble très intéressant, j’ai exécuté le code et je l’ai valgrind. Le résultat est le suivant.

 yjaeyong@carbon:~$ valgrind test ==14735== Memcheck, a memory error detector ==14735== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. ==14735== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info ==14735== Command: test ==14735== ==14735== ==14735== HEAP SUMMARY: ==14735== in use at exit: 0 bytes in 0 blocks ==14735== total heap usage: 32 allocs, 32 frees, 2,017 bytes allocated ==14735== ==14735== All heap blocks were freed -- no leaks are possible ==14735== ==14735== For counts of detected and suppressed errors, rerun with: -v ==14735== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 6) 

Cela signifie qu’aucune fuite n’est possible. Est-ce que je manque quelque chose?