Question

Pour autant que je peux dire, asprintf appelle malloc. Si je remplace malloc avec le GC Boehm, un appel à asprintf appelle toujours le malloc traditionnel - au moins ce que valgrind me dit:

Voici la macro malloc:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

#include <gc.h>
#define malloc(n)    GC_MALLOC(n)
#define calloc(m,n)  GC_MALLOC((m)*(n))
#define realloc(p,n) GC_REALLOC((p),(n))

typedef char * string;

Et voici le rapport valgrind:

hopcroft:didactic_scheme(flexible_strings) scotttaylor$ valgrind --suppressions=./boehm-gc.suppressions --leak-check=full bin/escheme -e 1
==16130== Memcheck, a memory error detector
==16130== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==16130== Using Valgrind-3.6.0.SVN and LibVEX; rerun with -h for copyright info
==16130== Command: bin/escheme -e 1
==16130== 
--16130-- bin/escheme:
--16130-- dSYM directory is missing; consider using --dsymutil=yes
1==16130== 
==16130== HEAP SUMMARY:
==16130==     in use at exit: 4,312 bytes in 3 blocks
==16130==   total heap usage: 3 allocs, 0 frees, 4,312 bytes allocated
==16130== 
==16130== 128 bytes in 1 blocks are definitely lost in loss record 2 of 3
==16130==    at 0x100012D75: malloc (vg_replace_malloc.c:236)
==16130==    by 0x1000918EC: asprintf (in /usr/lib/libSystem.B.dylib)
==16130==    by 0x1000013FA: printInt (in bin/escheme)
==16130==    by 0x100001D38: print (in bin/escheme)
==16130==    by 0x100001DC5: main (in bin/escheme)
==16130== 
==16130== LEAK SUMMARY:
==16130==    definitely lost: 128 bytes in 1 blocks
==16130==    indirectly lost: 0 bytes in 0 blocks
==16130==      possibly lost: 0 bytes in 0 blocks
==16130==    still reachable: 4,184 bytes in 2 blocks
==16130==         suppressed: 0 bytes in 0 blocks
==16130== Reachable blocks (those to which a pointer was found) are not shown.
==16130== To see them, rerun with: --leak-check=full --show-reachable=yes
==16130== 
==16130== For counts of detected and suppressed errors, rerun with: -v
==16130== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 66 from 13)

Voici le code dans lequel l'appel malloc vient:

static string printInt(Object self) {
  string str;
  asprintf(&str, "%lu", getValueInt(self));
  return str;
}

Une solution pourrait être d'utiliser asprintf, puis utilisez malloc pour le copier de sorte que la macro malloc est utilisé à la place de la fonction primitive:

static string printInt(Object self) {
  string tmp;
  string str;

  asprintf(&tmp, "%lu", getValueInt(self));
  str = calloc(sizeof(string), strlen(tmp) + 1);

  strcpy(str, tmp);
  free(tmp);

  return str;
}

Cela semble ridicule - il implique un tas de copie inutile et se trouve être également un oeil douloureux code IHMO. Ainsi est-il un moyen sûr d'utiliser asprintf et d'autres bibliothèques du système qui pourrait appeler le malloc natif tout en utilisant le Boehm GC? Y at-il une alternative à asprintf que je devrais utiliser à la place?

Était-ce utile?

La solution

snprintf renvoie le nombre de caractères qui auraient été écrits avaient le tampon fourni été assez grand. Vous pouvez appeler cette méthode deux fois (une fois pour obtenir la taille de la mémoire tampon à droite puis à nouveau avec un assez grand tampon pour obtenir la sortie), mais cela va probablement être moins efficace que la copie juste la sortie de asprintf dans un tampon de collection. Voici un exemple contenant du code qui prévoit d'allouer un tampon assez grand pour contenir la valeur maximale d'un unsigned long pour les systèmes 32 bits. Sur les systèmes où il n'y a pas assez d'espace, le tampon est réaffecté et reformaté.

#include <limits.h>

...

unsigned long intValue = getValueInt(self);
size_t maxLength = 11; // heuristic
char *buf = malloc(maxLength);

int result = snprintf(buf, maxLength, "%lu", intValue);
if (result > maxLength)
{
    // shouldn't ever get here, but just in case the buffer is too small
    // we reallocate it to the correct size and try again.
    buf = malloc(result);
    snprintf(buf, result, "%lu", intValue);
}

return buf;

Autres conseils

Selon cette page , vous pouvez compiler libgc ( la bibliothèque de Boehm-gc) avec

-DREDIRECT_MALLOC=GC_malloc -DIGNORE_FREE

qui devrait intercepter l'appel à malloc en asprintf. NB:. N'a pas essayé

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top