为什么我自己提供 malloc 和 free 函数时没有出现链接错误?

8
我将尝试实现一个简单的适应性首次匹配内存管理算法。因此,我有一个包含自己代码的C文件。
   void* malloc(size_t)

并且

   void free(void*)

当使用gcc生成一个.out文件时,我期望会出现链接错误,因为它会与现有的标准实现冲突。但是我的文件链接正常。请帮助我理解。

我认为这种使用链接顺序“覆盖”程序例程的做法被视为可接受的实践,因此默认情况下不会出现链接错误/警告。 - Paul R
3
它能够链接,但它是否真正运行您的代码?GCC具有malloc和free内建函数,可能会覆盖您的函数。 - idoby
4
@IBY提出了一个很好的观点 - OP可能需要使用-fno-builtin-fno-builtin-malloc -fno-builtin-free来确保其程序被调用。 - Paul R
使用共享库难道不是解决问题的好办法吗? - DCMaxxx
5
那么,您在使用哪个系统?如果是Linux系统,那么glibc中的malloc等函数都是弱符号,这意味着您可以用自己的函数来覆盖它们。 - nos
1
看这里: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Other-Builtins.html - idoby
2个回答

6

我预期会出现链接错误,因为它会与现有的标准实现冲突。

您的预期是不正确的:大多数 UNIX libc 实现都支持使用其他 malloc。为此,他们将 malloc、realloc、free 等函数放在单独的对象文件中,或者每个函数都放在它自己的对象文件中。

然后,链接器可以自由地用您的实现替换 libc.a 中的 malloc.o。您可以在这里了解链接器使用的算法。一旦您理解了算法,就应该清楚为什么链接您自己的 malloc 和 free 不会导致链接错误。

UNIX 共享库明确设计为模拟归档库,因此,尽管链接 libc.so 时您不会遇到链接错误的细节有所不同,但精神是相同的。

但是,您还没有完成。使用您的实现链接任何稍微复杂的程序很可能会崩溃,因为当您替换 malloc 时,还需要实现 realloc、calloc、memalign 和 posix_memalign 等函数。否则,您将得到混合实现,并且当有人传递 realloc 的指针给您的 free 时,事情很可能会爆炸。


0
在我的经验中,自定义的malloc和free通常被命名为独特的名称,例如内核malloc,kmalloc和内核free,kfree。如果您正在编写自己的代码,我建议为您的函数提供单独的名称。
您打算如何分配内存?大多数情况下,您应该围绕malloc函数提供自定义功能,但最终仍然会以某种形式使用malloc。在我看来,这是您应该采取的路线,因此除非您有充分的理由(或强烈的愿望)这样做,否则不要急于处理内置的malloc和free函数。将它们命名相同将干扰此过程。 这是malloc的Minix实现,只是为了让您了解您正在查看的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接