尽管有足够的可用 RAM,为什么 new/malloc 在 Win x64 上失败? [英] Why does new / malloc fail on Win x64 although there is plenty of free RAM?

查看:20
本文介绍了尽管有足够的可用 RAM,为什么 new/malloc 在 Win x64 上失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个强递归函数,它使用 new(递归到 malloc/calloc 在标准库中).尽管我在 Windows XP x64 上使用本机 64 位应用程序,但经过数百次递归后,新的失败.该机器有 10 GB RAM,该应用程序仅使用约 1GB.没有其他大型应用在运行.

I have a strongly recursive function, that creates a (very small) std::multimap locally for each function instance using new (which recurses to malloc/calloc in the std lib). After some hundred recursions new fails although i am using a native 64Bit application on Windows XP x64. The machine has 10 GB RAM, The application only uses about 1GB. No other big apps are running.

这会在启动程序并启动递归函数几分钟后发生.此时递归函数已被调用约 150.000 次,可能最大.数百个递归.发生的问题不是堆栈溢出.

This happens a few minutes after starting the program and starting the recursive function. The recursive function has been called about 150.000 times at this point with a probably max. recursion of some hundreds. The problem occurring is not a stack overflow.

我使用的是 Visual Studio 2005 和 dinkumware STL.错误发生在发布版本中.

I am using Visual Studio 2005 and the dinkumware STL. The fault occurs in a release build.

好的,这是一些代码.我现在重新排列代码并将地图放在堆栈上,但它使用 new 进行初始化 - 它失败了.我也尝试过使用 std::multimap 而不是 hash_multimap.所有这些都不会改变行为.

Ok, here is some code. I rearranged the code now and put the map on the stack, but it uses new to initialize - there it fails. I also tried with a std::multimap instead of hash_multimap. All of this die not change the behavior.

    int TraceBackSource(CalcParams *CalcData, CKnoObj *theKno, int qualNo, 
                            double maschFak, double partAmount, int MaschLevel, char *MaschID, 
                            double *totalStrFlow, int passNo, 
                            CTraceBackData *ResultData)

{   typedef std::hash_multimap<double, CStrObj *>StrFMap;
    StrFMap thePipes;

        for(...)
        {  
            ...
            thePipes.insert(std::make_pair(thisFlow, theStr));
        }

        // max. 5 elements in "thePipes"
        for(StrFMap::iterator it = thePipes.begin(); it != thePipes.end(); it++)
        {
            ...
            try
            {
                TraceBackSource(CalcData, otherKno, qualNo, maschFak * nodeFak, nodeAmount, SubMaschlevel, newMaschID, totalStrFlow, passNo, ResultData);
            }
            catch(std::exception &it)
            {   
                    Trace(0, "*** Exception, %s", it.what()); 
                    return 0;
            }

            return 0;
        }
}

有趣的是,第一次失败进入了 catch 处理程序,过了一段时间,我以 ACCESS VIOLATION 和损坏的堆栈结束.

Interestingly, the first failure runs into the catch handler, quite a bit later on i end with a ACCESS VIOLATION and a corrupted stack.

推荐答案

您的数字表明一个易于默认的 1MB 堆栈大小 (c150K x 8 ).因此,通过快速查看您的代码(尤其是 map::insert 而不是提供 for'...' 代码),您会遇到与 stackoverflow.com 的交互 :)

Your number suggests an easily defaulted 1MB stacks size (c150K x 8 ). So from a quick look at your code (and that map::insert especially and not providing the for'...' code ) you are running into an interaction with stackoverflow.com :)

您可能正在为运行它的操作系统点击它.在 Windows 上使用 VS 链接器设置或使用 editbin.exe 或一些奇异的不可移植 api,将堆栈大小增加三倍,看看它是否会显着改变异常时观察到的递归计数.

You are probably hitting it for the OS you're running it on. On Windows use the VS linker setttings or use editbin.exe or some exotic unportable api, triple your stack size and see whether it significantly changes the observed recursive count at time of exception.

这篇关于尽管有足够的可用 RAM,为什么 new/malloc 在 Win x64 上失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆