编译器之间free/malloc的兼容性问题

4
假设我有一个使用编译器A编译的库。它使用malloc()来分配内存,并让我使用free()来释放内存。它没有提供任何特殊的释放函数。
我可以使用编译器B编译使用该库的程序吗?或者我需要担心一个编译器的(标准库的)malloc与另一个编译器的free不兼容吗?
除了一般性问题外,我还想知道这些编译器的具体答案:在OS X上使用MacPorts的gcc 4.9或5的系统clang。

一般来说,使用编译器A编译的库与编译器B不兼容。即使编译成功,也不能保证生成的程序能正常工作。话虽如此,clang确实致力于与gcc兼容,因此它可能会起作用,但这种行为完全取决于编译器,并且必须在您的情况下进行特定测试。 - UnholySheep
5
@UnholySheep,你的评论几乎对除Windows外的任何操作系统都不正确。有一种叫做ABI的东西可以确保这种兼容性。在Windows上这个问题比较模糊,因为不同的编译器供应商有/曾有不同的调用约定,但在类UNIX操作系统中,每个操作系统都有一个单一的ABI,因此由一个编译器生成的库可以与另一个编译器编译的库进行交互操作。当然,如果你非常努力地尝试,你也可以故意打破这个规则,但它适用于除了这种情况以外的所有情况。 - fuz
在MacOSX上,Clang和GCC可以很好地配合使用。在这两种情况下,mallocfree由libc.dylib提供,该库随操作系统一起提供而不是编译器。如果编译C ++,甚至可以在同一个可执行文件中混合使用clang的libc ++和GNU libstdc ++。此外,请注意,如果您安装了Xcode命令行工具选项,则从命令行调用gcc实际上会给您提供clang,在绝大多数情况下,这不是问题。 - marko
2
至少可以说这是一个糟糕的库设计,仅仅因为你在问。因此,针对你第二段问题的答案是:我认为如果你能用编译器B编译你的程序,那么是的,你应该担心在编译器A中编译的库不兼容的情况。(关于@FUZxxi的评论,这个评论来自一个大部分时间都在Windows上度过的人) - ryyker
@marko - 多数情况下,这不是一个问题。但这并不能让我放心。令我担心的是 X,其中 X == (所有时间) - (多数情况下的时间) - ryyker
显示剩余3条评论
2个回答

3
这不应该是一个问题。操作系统的ABI规定了程序如何调用库函数,所有程序和库都应该遵守这个规定。这样可以将使用不同编译器创建的程序链接在一起。
你的问题表明你对编译器和库存在一些混淆。用编译器A编译库并不意味着它使用了库A的malloc函数。库是在连接步骤中指定的,而不是在编译库时指定。当你创建可执行程序时,你需要将主程序与你编译的库和C运行时库链接起来。malloc和free在C运行时库中提供,最终生成的可执行文件只会有一个。

我不知道ABI规范涉及什么。那么我可以假设C标准库中的所有内容(包括freemalloc)都是可互操作的吗?我很担心,因为许多库为此提供了自己的free函数(但有些没有)。 - Szabolcs
当你链接一个库时,你会得到它所有的函数。因此,如果你正在使用库A的malloc,你也在使用它的free,它们将一起工作。 - Barmar
但这不是 OP 所问的。出于某种原因,OP 特别询问一个库中的 malloc 和另一个库中的 free - kaylum
@AlanAu 然后他在问一些实际上并不会发生的事情。据我所知,你不能从不同的库中挑选和选择函数。 - Barmar
同意。所以对于 OP 的问题,答案实际上是“不可以假定它们是兼容的”。后续问题是 - 为什么你要这样做,你真的需要吗? - kaylum
显示剩余7条评论

2
“free”和“malloc”在编译器之间并不总是兼容的。具体来说,它们在MSVC和MinGW之间不兼容。
我遇到了以下情况:
我正在使用一个C库,该库有一个返回数组的函数。当不再需要该数组时,用户必须使用“free”释放它。我正在使用使用MSVC预编译的此库的DLL。然而,该DLL是使用MinGW编译的。在使用MSVC的“free”释放使用MinGW的“malloc”分配的内存时会导致崩溃。但是,确保始终使用兼容的“free”/“malloc”对避免了麻烦,即使我的程序使用不同的C编译器也是如此。

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