4

我为我定义了一个 mem_malloc() 和 mem_free(),我想用它们来替换 malloc() 和 free(),从而替换 C++ 的 new 和 delete。

我将它们定义如下:

extern "C" {

extern void *mem_malloc(size_t);
extern void mem_free(void *);

void *
malloc(size_t size) {
  return mem_malloc(size);
}

void
free(void *memory) {
  mem_free(memory);
}
}

但是,我收到两个链接错误:

[user@machine test]$ g++ -m32 -pthread main.cpp -static  libmemnmf-O.a
/usr/lib/../lib/libc.a(malloc.o): In function `free':
(.text+0x153c): multiple definition of `free'
/tmp/ccD2Mgln.o:main.cpp:(.text+0x842): first defined here
/usr/lib/../lib/libc.a(malloc.o): In function `malloc':
(.text+0x3084): multiple definition of `malloc'
/tmp/ccD2Mgln.o:main.cpp:(.text+0x856): first defined here
libmemnmf-O.a(mem_debug.o): In function `mem_init_debug_routines':
mem_debug.c:(.text+0x83c): undefined reference to `dlopen'
mem_debug.c:(.text+0x89d): undefined reference to `dlsym'
mem_debug.c:(.text+0xa03): undefined reference to `dlclose'
mem_debug.c:(.text+0xa24): undefined reference to `dlclose'
mem_debug.c:(.text+0xa2e): undefined reference to `dlerror'
collect2: ld returned 1 exit status

1)如何让多重定义的 malloc() 和 free() 错误消失,只采用我的定义而不是内置的?

2) 什么库提供 dlopen() 和朋友?我希望这是内置的,但它们是未定义的。

4

5 回答 5

4

我假设您在您尝试编译的 main.cpp 文件中定义 malloc 和 free 并且 mem_alloc 和 mem_free 位于 libmemnmf-0.a

可能发生的情况是 main.cpp 中的一些引用需要来自 glibc 的对象。具体来说,是动态加载库(dlopen)。此代码包含在 glibc 中(用于回答问题 2)。当链接器包含来自 glibc 的对象并发现这些对象需要 malloc/free 符号时,它将尝试直接从 glibc 库中包含 malloc/free。由于您的 -static 链接器标志,整个 libmemnmf-0.a 库静态包含在您的可执行文件中。这显然会在您的可执行文件中包含另一个 malloc 和 free 对象。

您应该做的是将 malloc 和 free 例程放在一个单独的 .o 文件中,然后将该文件添加到您的链接命令中的某个位置,最好是在最后(假设您没有在该行以特殊方式指定标准库)。.o 文件将满足所有符号请求,并且 glibc 库将在 dlopen 或其他对象需要它们时发现这些匹配已解决。不同之处在于 libmnef-0.a 文件是一个库,链接器处理库的方式与处理简单对象的方式不同(这与通过库以解析该库中对象请求的符号的次数有关)。或者,您可以删除 -static 标志,我希望它也可以解决该问题,但您可能有充分的理由包含该标志开始。

如果您想覆盖 new 和 delete 的行为,您还可以考虑为类重载 operator new 和 operator delete 以提供特定于类的分配方法或内存池。

于 2010-12-06T09:18:21.050 回答
2

尝试:

#define free mem_free
#define malloc mem_alloc

包括stdlib.h

2.) dlopen() 和朋友们:

#include <dlfcn.h>

链接器标志:-ldl

请参见dlopen(3) 手册页

于 2010-12-06T09:01:51.427 回答
1

您默认链接到定义 malloc 的 libc,尝试使用#define 重命名。dlopen 等在ld中定义。

于 2010-12-06T09:04:19.353 回答
1

LD_LIBRARY_PATH您可以使用andLD_PRELOAD环境变量为库提供优先权。

这将允许您提供自定义mallocfree动态库,该库将主导 libc 提供的库。我相信这比#define基于 - 的解决方案更可取。

于 2010-12-06T09:09:15.493 回答
0

我一直在寻找这个答案。最后我找到了适合我的东西。链接器具有您可以使用的 --wrap=symbol 选项。

man ld

并搜索“wrap”,了解详细信息。

我发布了这个,以防有人发现这个问题,但没有一个答案对他有用,就像我自己的情况一样。

于 2015-07-25T18:42:30.087 回答