替换malloc实现

时间:2017-11-06 21:22:46

标签: c++ malloc

我有一个c ++程序,它是通过JNI从java程序调用的,我想用C ++程序中的内存分配器替换Doug Lea的dlmalloc实现(IIUC这是可行的,因为新的操作符调用了malloc下面的)。我还在我的c ++程序中使用std:list和std:map,并希望这些库函数在调用" new"时也会使用dlmalloc。运营商。我试过使用LD_PRELOAD,但似乎也会导致dmalloc也会从JAVA程序调用,我不想要它。在编译时将c ++程序与libdlmalloc.so链接起来是否足以保证所有c ++库函数都使用dlmalloc?如果是这样,可以提供一个如何链接dlmalloc的示例?感谢

2 个答案:

答案 0 :(得分:1)

如果您的程序没有调用任何分配您需要释放的内存的libc函数(例如realpath),您可以将静态链接到dlmalloc并仔细管理导出的集合符号。如果您只导出那些由JNI接口实际调用的函数(而不是mallocfree等),这应该可以。

JNI API具有回调函数,这些函数将调用malloc / free,这些函数将保留原始进程中的函数,但事情将保持一致,因为malloc / {{ 1}}实现将匹配。

但是,您应确保您的dlmalloc变体不使用free / brk,仅使用sbrk来分配操作系统,因为较旧的分配形式可能会干扰系统mmap

对于ELF环境中的符号管理,Ulrich Drepper's How To Write Shared Libraries的第2.2节(导出控制)是一个很好的参考。

答案 1 :(得分:0)

我不一定认为使用链接器玩游戏很糟糕,但我有另一种选择......

如果dlmalloc有一个符号不是'malloc'的库,你可以使用自己的版本覆盖全局C ++ operator newoperator new[]operator deleteoperator delete[]调用malloc和free的dlmalloc版本。

这将导致所有C ++分配都经历您的重载,包括库函数。标准保证了这种行为。但是,如果你有两个不同版本的这些重载,那么它是未指定的,它被称为。但很明显,如果标准库本身有一个版本,那么你的版本应该优先。

这不会涵盖您可能调用的任何C标准库函数。无论如何,它们仍将使用malloc符号,如果不使用链接器玩游戏,则无法做到这一点。幸运的是,在大多数C ++程序中,标准C库的调用方式不会很多。

重新编译程序是不够的。实际上,由于newdelete运算符的标准C ++实现没有出现在标准库头中,所以它在很大程度上无法完成任何事情,因此预处理器无法替换{{1}使用dlmalloc库提供的任何功能。