Est-il possible de trouver la mémoire allouée au pointeur sans rechercher l’instruction malloc

Supposons que j’ai alloué de la mémoire à un pointeur dans une fonction foo :

 void foo() { // ... int *ptr = malloc(20*sizeof(int)); bar (ptr); } 

De foo() , je passe ce pointeur à bar() et disons de bar() à une autre fonction.

Maintenant, à un moment donné, je veux vérifier: combien de mémoire a été allouée au pointeur.

Est-il possible, sans chercher la déclaration:

 int *ptr = malloc(20*sizeof(int)); 

déterminer la quantité de mémoire allouée au pointeur à l’aide de GDB?

Merci.

La réponse est: ça dépend .

De nombreux systèmes fournissent msize() [1], malloc_usable_size() [2] ou une fonction similaire. Si vous êtes sur un tel système, (gdb) print malloc_usable_size(ptr) tout ce dont vous avez besoin est (gdb) print malloc_usable_size(ptr) .

[1] http://msdn.microsoft.com/en-us/library/z2s077bc(v=vs.80).aspx
[2] http://www.slac.stanford.edu/comp/unix/package/rtems/doc/html/libc/libc.info.malloc.html

En général non. C ne fournit pas un moyen d’obtenir la taille d’un bloc de mémoire alloué. Vous devez suivre la quantité de mémoire que vous avez allouée.

MAIS , dans certaines bibliothèques C, il existe une fonction permettant d’obtenir la taille utilisable d’un bloc de mémoire – malloc_usable_size (trouvée dans sur les systèmes Linux, sans page de manuel). Notez que cela ne fonctionne pas sur toutes les bibliothèques et peut signaler une valeur supérieure à celle que vous avez demandée. S’il vous plaît, utilisez-le uniquement pour le débogage.

Pour être complet, ma réponse initiale, qui plonge dans les métadonnées de tas de bas niveau, avant @Employed Russian pointant du doigt sur malloc_usable_size :

MAIS , vous pourrez peut-être extraire cela manuellement. Notez toutefois que tout cela peut varier en fonction de votre système d’exploitation, de votre architecture de processeur et de votre bibliothèque C. Je suppose que vous utilisez eglibc 2.12.1; vos résultats peuvent varier n’importe où ailleurs.

AVERTISSEMENT : sérieusement, NE l’utilisez PAS sauf pour le débogage dans gdb. Vraiment. Je suis sérieux.

L’allocateur de mémoire glibc stocke des morceaux de mémoire comme ceci (dans un commentaire doc dans malloc / malloc.c ):

  chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of previous chunk, if allocated | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of chunk, in bytes |M|P| mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | User data starts here... . . . . (malloc_usable_size() bytes) . . | nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size of chunk | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 

Vos données sont à ‘mem’ ici, et la taille du morceau inclut l’en-tête. L’indicateur P indique si les données du bloc précédent est valide et M indique qu’il s’agit d’un mappage mmap (pour les grands mallocs). Tout cela n’est pas trop important; l’important est que la taille vive d’un incrément de la taille d’un pointeur avant votre mémoire; il vous suffit de masquer ces indicateurs et de soustraire la taille de l’en-tête:

 Breakpoint 1, main () at test.c:8 8 char *a = malloc(32); (gdb) n 10 free(a); (gdb) print (*((unsigned long long*)a - 1) & ~3) - sizeof(unsigned long long)*2 $14 = 32 

Avertissement: la taille effectivement atsortingbuée peut être supérieure à celle que vous avez demandée. N’essayez pas d’être intelligent et d’utiliser l’excès. Demandez combien vous avez besoin au début.

Mise en garde 2: Cela ne fonctionne qu’avec la glibc. Et cela ne fonctionne qu’avec certaines versions de glibc. et donc peut casser à tout moment sans aucun avertissement. Je ne saurais trop insister là-dessus. NE l’ utilisez PAS dans votre code actuel; uniquement pour le débogage lorsque toutes les autres options sont épuisées. Votre code doit suivre lui-même la taille de ses tampons.

Non Vous devez stocker cette information vous-même lorsque vous malloc() .