一段时间以来,我一直很高兴地使用dlmalloc进行跨平台项目(Windows,Mac OS X,Ubuntu)。然而,最近,似乎使用dlmalloc会导致Windows 7上的崩溃 -
为了确保在我的项目中它不是一件傻瓜,我创建了一个超级最小的测试程序 - 它除了从main返回之外什么都不做。一个版本(“malloctest
”)链接到dlmalloc而另一个版本(“regulartest
”)则没有。在WinXP上,两者都运行正常。在Windows 7上,malloctest
崩溃。您可以看到测试here的截屏视频。
我的问题是:为什么会这样?这是dlmalloc中的错误吗?或者Windows 7中的加载程序是否已更改?有解决方法吗?
fyi,这是测试代码(test.cpp):
#include <stdio.h>
int main() {
return 0;
}
这是nmake makefile:
all: regulartest.exe malloctest.exe
malloctest.exe: malloc.obj test.obj
link /out:$@ $**
regulartest.exe: test.obj
link /out:$@ $**
clean:
del *.exe *.obj
为简洁起见,我不会在这篇文章中包含dlmalloc源代码,但你可以得到它(v2.8.4)here。
编辑:查看其他相关SO帖子:
答案 0 :(得分:2)
看起来像C运行时中的错误。在Windows 7上使用Visual Studio 2008,我重现了同样的问题。通过在dlmalloc
和dlfree
中放置断点进行一些快速调试后,我看到dlfree
被调用的地址从未在dlmalloc
之前返回,然后是此后不久就会发生访问冲突。
值得庆幸的是,C运行时的源代码与VS一起分发,因此我可以看到此free
的调用来自__endstdio
中的_file.c
函数。相应的分配在__initstdio
,并且正在调用_calloc_crt
来分配其内存。 _calloc_crt
调用_calloc_impl
,调用HeapAlloc
来获取内存。 _malloc_crt
(在C运行时的其他位置使用,例如为环境和argv
分配内存),另一方面,直接调用malloc
和_free_crt
直接拨打free
。
因此,对于使用_malloc_crt
分配并使用_free_crt
释放的内存,一切都很好,花花公子。但对于使用_calloc_crt
分配并使用_free_crt
释放的内存,会发生不好的事情。
我不知道是否支持替换这样的malloc
- 如果是,那么这是CRT的错误。如果没有,我建议调查一个不同的C运行时(例如MinGW或Cygwin GCC)。
答案 1 :(得分:2)
在跨平台代码中使用dlmalloc
是一种矛盾。替换任何标准C函数(尤其是malloc
和族)会导致未定义的行为。与可替换malloc
的可移植方法最接近的是使用搜索和替换(不是#define
;也是UB)来调用源文件(例如)my_malloc
而不是malloc
。请注意,内部C库函数仍将使用其标准malloc
,因此如果两者发生冲突,事情仍会爆发。基本上,尝试替换malloc
实际上是错误的。如果您的系统确实有一个损坏的malloc
实施(太慢,太多碎片等),那么您需要以特定于实现的方式进行替换,并在所有系统上禁用替换,除了您的系统。仔细检查了您的特定于实现的替换是否正常工作。