我有一个c ++程序,我在Windows 7 64位机器上运行,使用Eclipse作为我的IDE。我使用mingw32作为编译器。
问题:当我使用gdb调试器调试程序时,它运行得很好并完成它需要做的事情。但是当我在没有调试的情况下运行它时,无论是从命令行还是从eclipse中运行(使用与调试相同的配置),它都会崩溃。 我尝试从命令行运行程序并使用调试器附加到进程,我看到的是它到达以下代码行:
anc_map[ancestry].hap_array = (char**)calloc(anc_map[ancestry].nr_hap , sizeof(char*));
并且只是挂起(cpu不工作,虽然程序仍在运行但没有任何反应)。
上面的行实际上被调用了不止一次,并且在第二次调用时发生了挂起(它第一次工作)。
知道造成这种行为的原因是什么?
谢谢, 伊塔马尔。
修改:
答案 0 :(得分:0)
首先想到的是anc_map[ancestry].nr_hap
是否可能是一些虚假的,可能是巨大的数字。可能是因为任何变量都被破坏了。我不确定为什么它只会在没有调试器的情况下被破坏,但可能是调试器会影响分配的位置,并且在调试时腐败出现的危害较小。
另一件需要考虑的事情是,如果程序需要大量内存,调试器可能会影响Windows中的2 GB限制标志,因此在一种情况下有足够的内存,另一种方法是用完。但是,我不知道如何使用mingw32编译器更改它,因为我只使用Microsoft(Microsoft link
和editbin
的/ LARGEADDRESSAWARE选项)。原因是,在一些旧软件中,他们注意到人们正在进行像(whatever *)(((unsigned)begin + (unsigned)end)/2)
这样的二分查找,除了错误的C之外,如果指针超过2GB,则不起作用,因为计算溢出。因此,对于旧软件,在超过2GB之前编写,它们将内存限制为2GB并提供了更多的选项,这意味着32位Windows上的3GB(最后1GB映射内核空间以避免在内核条目上交换页表退出; linux做同样的事情)和4GB用于64位窗口上的32位进程(内核可以映射到4GB以上)。
嗯,但很可能它实际上是内存管理元数据的损坏,因为这是通常的情况,内存分配或释放功能只是挂起而不是返回错误。同样,调试器会导致某些地址不同,并且腐败会发生在其他地方。
在第一个也是最后一个案例中,腐败可能总是在那里,所以你可能有一些运气试图运行它: