如何将 asprintf 与 Boehm GC 结合使用?
据我所知,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 调用的代码from:
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 和其他可能调用本机 malloc 的系统库,同时仍然使用 Boehm GC?我应该使用 asprintf 的替代方案吗?
As far as I can tell, asprintf calls malloc. If I replace malloc with the Boehm GC, a call to asprintf still calls the traditional malloc - at least that's what valgrind is telling me:
Here's the malloc macro:
#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;
And here is the valgrind report:
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)
Here's the code in which the malloc call is coming from:
static string printInt(Object self) {
string str;
asprintf(&str, "%lu", getValueInt(self));
return str;
}
A workaround might be to use asprintf, then use malloc to copy it
so that the malloc macro is used instead of the primitive function:
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;
}
That seems silly - it involves a bunch of unnecessary copying and also happens to be a code eye sore IHMO. So is there a safe way to use asprintf and other system libraries that might call the native malloc while still using the Boehm GC? Is there an alternative to asprintf that I should be using instead?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
snprintf
返回如果提供的缓冲区足够大则将写入的字符数。您可以调用此方法两次(一次是为了获取正确的缓冲区大小,然后再次使用足够大的缓冲区来获取输出),但是这可能比仅复制 asprintf 的输出效率低> 进入可收集的缓冲区。下面的示例包含分配足够大的缓冲区以包含 32 位系统的 unsigned long 最大值的代码。在没有足够空间的系统上,缓冲区将被重新分配并重新格式化。snprintf
returns the number of characters that would have been written had the provided buffer been large enough. You could call this method twice (once to get the right buffer size and then again with a buffer large enough to obtain the output), however this is probably going to be less efficient than just copying the output ofasprintf
into a collectable buffer. Here's an example containing code that allocates a buffer large enough to contain the maximum value of an unsigned long for 32-bit systems. On systems where there is not enough space, the buffer is reallocated and reformatted.根据这个页面,可以编译libgc(boehm- gc 库),
应该拦截调用 到 asprintf 中的 malloc。注意:还没有尝试过这个。
According to this page, you can compile libgc (the boehm-gc library) with
which ought to intercept the call to malloc in asprintf. NB: haven't tried this.