一个链表new第二个节点时失败,为什么会出现这样的问题?怎么解决?我的程序中大量使用new如果用windows的内存管理API来修改程序,会很麻烦,希望大家能帮帮我,谢谢

解决方案 »

  1.   

    我几乎没碰到过这种情况,每次编码如果new失败一般就让函数返回false了。
    那位大哥清楚stl或boost是如何处理new失败的?
      

  2.   

    链表结构是自己定义的吗?如果是的话,看看你的链表结构中是否存在越界的情况,在这种情况下会出现new失败!
      

  3.   

    struct PCIConfigSpace
    {
    DWORD VendorID;//00h 0--15
    DWORD DeviceID;//02h 16--31
    DWORD Command;//04h 0--15
    DWORD Status;//06h 16--31
    DWORD RevisionID;//08h 0--7
    DWORD ClassCode;//09h 8--31
    DWORD CacheLineSize;//0Ch 0--7
    DWORD LatencyTimer;//0Dh 8--15
    DWORD HeaderType;//0Eh 16--23
    DWORD BIST;//0Fh 24--31
    DWORD BaseAddressRegister[6];
    DWORD CardbusCISPointer;//28h
    DWORD SubsystemVendorID;//2Ch 0--15
    DWORD SubsystemID;//2Eh 16--32
    DWORD ExpansionROMBaseAddress;//30h
    DWORD CapabllltlesPolnter;//34h
    DWORD Reserved0;//35h 3bytes 8--31
    DWORD Reserved1;//38h 4bytes
    DWORD InterruptLine;//3Ch 0--7
    DWORD InterruptPin;//3Dh 8--15
    DWORD Min_Gnt;//3Eh 16--23
    DWORD Max_Lat;//3Fh 24--31
    };
    struct PCIConfigList//链表
    {
    PCIConfigList * previous;//前一个列表指针
    PCIConfigSpace   PCIConfs;
    TCHAR * pstrbuf,* pstrbufpos;//寄存器解释字符串0
    DWORD pstrbufsize;
    TCHAR * pstrbuf1,* pstrbufpos1;//寄存器解释字符串1
    DWORD pstrbuf1size;
    TCHAR * pstrbuf2,* pstrbufpos2;//寄存器解释字符串2
    DWORD pstrbuf2size;
    TCHAR * pstrbuf3,* pstrbufpos3;//寄存器解释字符串3
    DWORD pstrbuf3size;
    TCHAR * pstrbufAll,* pstrbufposAll;//全局解释字符串All
    DWORD pstrbufAllsize;
    PCIConfigList * next;//下一个列表指针
    };
    这个链表还不到128字节,怎么也不会是堆太小啊,以前new过100M的数组应该不会吧建议捕获异常,然后权横怎么做,再次分配还是通过别的方式分配空间。
    ////////////////////////////////////////////////////////////////
    用什么方式?new过不去,我的代码就要动大手术了,以前也碰到过这样的事情,导致我放弃了那段代码,现在呜........呜.........难道............
      

  4.   

    DWORD BaseAddressRegister[6];
    检查一下这个成员,看看是否又越界!
      

  5.   

    1) Double check if memory is low.
    2) If memory is not low, your heap may be corrupted. Use functions like _CrtCheckMemory to check heap.
      

  6.   

    使用_set_new_handler安装错误捕捉函数。
    当new无法满足要求时,它会在抛出异常之前调用你的错误处理函数。_set_new_handler是头文件<new.h>中提供的一个函数,用法如下:
    #include <stdio.h>
    #include <new.h>// Define a function to be called if new fails to allocate memory.
    int MyNewHandler( size_t size )
    {
        clog << "Allocation failed. Coalescing heap." << endl;    // Call a fictitious function to recover some heap space.
        return CoalesceHeap();
    }void main()
    {
        // Set the failure handler for new to be MyNewHandler.
        _set_new_handler( MyNewHandler );    int *pi = new int[BIG_NUMBER];
    }
      

  7.   

    更详细请在msdn中查找set_new handler。不过我觉得你这个情况应该不是内存不够的缘故。有一次在dll中我分配内存竟然不够,改用VirtualAlloc就好了。而且也不是堆太小。
      

  8.   

    To 楼主
    对于大内存的分配你可以用VirtualAlloc或者内存映射文件,这样绕开了堆栈空间的问题,可以直接使用虚拟内存。To 袁峰
    _CrtCheckMemory 只能应用在Debug版的程序当中,如果在Release中才会出现内存不足,又应该怎么办呢?
      

  9.   

    哦 高实在是高!
    重载以下new 然后采用MS的API 我觉得还是可以的
      

  10.   

    > _CrtCheckMemory 只能应用在Debug版的程序当中,如果在Release中才会出现内存不足,又应该怎么办呢?If it's reall out of memory, there are a few things to do:1) Change your program to use less memory. It's usually always possible.
    2) Increase your system page file size.
    3) Rebase DLLs to make virtual memory less fragmented.
    4) Use the 3gb user memory option.
    5) Move to 64-bit machine.But most likely reason is a heap corruption. Most such problems are easier to identify in debug mode. If it really only happens in release mode. I would try:
    1) Figure out the structure of CRT runtime heap. Source code included, right?
    2) Write my own heap walking code.
    3) Call the heap walking code from time to time to find the first place such corruption happens.
    4) Reduce code piece by piece until the problem disappears, then check the last piece of code.
    5) Sometimes, just read the code around it careful will find the problem.
      

  11.   

    谢谢,看起来Release才可能出现的内存不足问题真是很可怕的。对于可能发生的内存不足,最好还是在设计阶段预见并解决,我曾经用内存文件来分配空间,这样,可以充分使用叶面文件,解决了大内存需求的问题。
      

  12.   

    如果是大内存的分配,可以使用函数GlobalAllocPtr或者GlobalAlloc  (前者在MSDN上查不到,不过用法和后者一样)
    对于楼主的问题,不应该是内存不足,我以前曾经试过分配80M的内存进行操作,都没有问题;记得NEW分配内存好象是有一个限制,属于系统限制,因为该函数是16位操作系统时候出现的,那个时候的可分配内存不能过大
      

  13.   

    我还没见过New会出错的情况呢? 厉害。
    如果new出错,一般是Exit了。
      

  14.   

    new int[?];  ? is a validate value??
      

  15.   

    我想楼主是程序那里有问题,然后才导致new时出错。
    如果真是内存不足的话,就提示用户内存不足呀。
    在MFC中当出现不足时会抛出异常,而没有MFC时VC会反回一个
    NULL,注意这个就可以了
      

  16.   

    呵呵!我记起搂主了!楼主是VC/MFC 硬件/系统的斑主吧!
    高考考得如何?
      

  17.   

    release出现内存异常最难查,弄出一堆AfxMessageBox当断点使阿
      

  18.   

    release版也可以调试,需要改些编译器的设置!
      

  19.   

    不是对象。 试下用malloc 分配内存。
    Free 释放内存。
      

  20.   

    呵呵!我记起搂主了!楼主是VC/MFC 硬件/系统的斑主吧!
    高考考得如何?
      

  21.   

    好几天不能上网,痛苦ing谢谢大家的关心,问题已经解决.////
    楼上的朋友们,这个程序用的内存不大,不用内存映射,还有,我检查了不是内存溢出,是因为new返回0造成的.
    回FengYuanMSFT
    1) Double check if memory is low.
    2) If memory is not low, your heap may be corrupted. Use functions like _CrtCheckMemory to check heap._CrtCheckMemory我没去试,我已经修改用VirtualAlloc了
    我发现不能用new内分配稍微复杂的点的结构
    如上面的结构,如果这样写,new就会返回0
    for(;;)
    {
    ......
    head->next=new PCIConfigList;
    ......
    (head->next)->pstrbuf=new TCHAR[4096];
    }
    应该不会是堆空间不够的问题,因为for(;;)总共分配内存最多512K,而且分配到第二个节点用不了多少内存
    后来我把(head->next)->pstrbuf=new TCHAR[4096]去掉;把所有节点的pstrbuf都指向一个VirtualAlloc分配的一个大内存(256k)上后,问题解决实在想不通
    head->next=new PCIConfigList;
    ......
    (head->next)->pstrbuf=new TCHAR[4096];这两个分配内存的操作居然相互影响,希望FengYuanMSFT能帮忙解释一下回Hawk_lp:不好意思,高考考的不好,我发现我的心就没再学习上,语文挂了80分左右,理综中的强项物理也挂了,化学我从来就没学过,.........
      

  22.   

    It looks like your code has heap corruption. new, which uses C runtime library, may be sensitive to the corruption; while VirtualAlloc may not.Use _CrtCheckMemory and related functions to check your heap.