Frage

Soweit ich das beurteilen kann, ruft asprintf malloc. Wenn ich malloc mit dem GC Boehm ersetzen, ein Aufruf an asprintf noch die traditionelle malloc nennt - zumindest das ist, was valgrind sagt mir:

Hier ist der malloc Makro:

#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;

Und hier ist der valgrind Bericht:

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)

Hier ist der Code, in dem der malloc Anruf kommt:

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

Eine Abhilfe könnte sein asprintf zu verwenden, dann malloc verwenden, es zu kopieren so dass die malloc Makro anstelle der ursprünglichen Funktion verwendet wird:

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;
}

Das scheint dumm - es beinhaltet eine Reihe von unnötigem Kopieren und geschieht auch ein Code Auge wund IHMO zu sein. So ist es eine sichere Art und Weise asprintf und andere Systembibliotheken zu verwenden, die das native malloc nennen könnte, während immer noch die Boehm GC? Gibt es eine Alternative zu asprintf, dass ich stattdessen verwenden sollte?

War es hilfreich?

Lösung

snprintf gibt die Anzahl der Zeichen, die geschrieben worden wäre, die zur Verfügung gestellt hatte Puffer groß genug gewesen. Sie könnten diese Methode aufrufen, zweimal (einmal die richtige Puffergröße zu bekommen und dann wieder mit einem Puffer groß genug, um die Ausgabe zu erhalten), aber dies wahrscheinlich weniger effizient sein wird als nur die Ausgabe von asprintf in einem sammelbaren Puffer zu kopieren. Hier ist ein Beispiel-Code enthält, dass ein zuordnet groß genug Puffer den maximalen Wert eines unsigned long für 32-Bit-Systeme enthalten. Auf Systemen, bei denen es nicht genügend Platz vorhanden ist, wird der Puffer neu zugewiesen und neu formatiert.

#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;

Andere Tipps

Nach dieser Seite , können Sie kompilieren libgc ( die boehm-gc-Bibliothek) mit

-DREDIRECT_MALLOC=GC_malloc -DIGNORE_FREE

was sein abfangen dem Aufruf zu malloc in asprintf. NB:. Habe nicht versucht

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top