据我所知,Asprintf致电Malloc。如果我用Boehm GC替换Malloc,那么ASPRINTF的电话仍然称为传统Malloc-至少这就是Valgrind告诉我的:

这是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;

这是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)

这是Malloc呼叫来自的代码:

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

解决方法可能是使用ASPRINTF,然后使用Malloc复制它,以便使用Malloc宏代替原始函数:

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

这似乎很愚蠢 - 它涉及一堆不必要的复制,也恰好是代码眼睛的IHMO。因此,是否有一种安全的方法使用ASPRINTF和其他系统库,这些库可能在仍在使用BOEHM GC时可以调用本机Malloc?我应该使用ASPRINTF的替代方案吗?

有帮助吗?

解决方案

snprintf 返回如果提供的缓冲区足够大,那将写的字符数量。您可以两次调用此方法(一次获得正确的缓冲尺寸,然后再用足够大以获得输出的缓冲区),但是,这可能比仅复制的输出效率不那么效率 asprintf 进入可收集的缓冲区。这是一个示例,其中包含代码,该代码分配了足够大的缓冲区,以包含32位系统的无符号长度的最大值。在没有足够空间的系统上,缓冲区将重新分配和重新格式化。

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

其他提示

根据 这一页, ,您可以使用

-DREDIRECT_MALLOC=GC_malloc -DIGNORE_FREE

应该 拦截电话 到Asprintf中的Malloc。 NB:没有尝试过。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top