CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 19

Hybrid View

  1. #1
    Join Date
    Mar 2005
    Posts
    11

    Question Windows CE (STL + std::bad_alloc + CMemoryException, ...)

    Hi,

    I'm building an application for Windows CE and Windows Desktop. The cross compilation is possible using some preprocessor directive, a different VS project file and a different VS solution file.

    As my application must be robust, I need to test each memory allocation and in the case of an memory allocation failure . I want to be able to correctly clean the previously allocated resources.

    Here is an exemple to show you my actual problem :

    Code:
    #include <list>
    using namespace std;
    
    typedef struct _MyObject
    {
        int a[9999];
    } MyObject;
    
    int i = 0;
    MyObject p;
    list<MyObject> v;
    try
    {
        // Force failure
        for (; i < 999999; ++i)
        {
            v.push_back(p);
        }
    }
    catch(CMemoryException* er)
    {
        DEBUG_ALERT("CMemoryException !");
    }
    catch(std::bad_alloc& er)
    {
        DEBUG_ALERT("bad_alloc error !");
    }
    And the following file (NewHandler.cpp) is only include on Windows CE (To force a std::bad_alloc) uppon a memory failure. As Windows CE malloc returns NULL instead of throwing std::bad_alloc exception.

    Code:
    // http://msdn.microsoft.com/en-us/magazine/cc164087.aspx
    #include <new>
    #include <new.h>
    
    // 4073: initializers put in library initialization area
    #pragma warning(disable: 4073)
    
    #pragma init_seg(lib)
    
    namespace
    {
    
       int new_handler(size_t) 
       {
           throw std::bad_alloc();
           return 0;
       }
    
       class NewHandler
       {
       public:
           NewHandler() 
           {
               m_old_new_handler = _set_new_handler(new_handler);
           }
        
           ~NewHandler() 
           {
              _set_new_handler(m_old_new_handler);
           }
    
       private:
           _PNH m_old_new_handler;
    
       } g_NewHandler; 
    }
    On Windows Desktop the program allocate memory until a CMemoryException is thrown. This is the result I want also on Windows CE.

    On Windows CE, the program allocate memory until the device show a popup message with the message "Memory system is very low". So I cannot intercept the moment when the first allocation failed ! Result, my program crash and the device too ! Not wise !.

    Is there any way to circumvent this problem ?

    I don't understand how can we catch memory problem on Windows CE, if we have NO WAY to detect it ? Take the list container as exemple, the push_back function returns nothing (void) and it doesn't throw any exeption when failing. So how can I more secure my code about allocation failure ?

    Best regards,
    Martin

  2. #2
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Windows CE (STL + std::bad_alloc + CMemoryException, ...)

    Did you try using _set_new_mode?

    What exactly do you want your program to do in case memory cannot be allocated? Do you want to handle this locally in your code or do you just want to exit the application cleanly? In the latter case, with careful use of RAII you could just call exit in the new handler.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  3. #3
    Join Date
    Mar 2005
    Posts
    11

    Re: Windows CE (STL + std::bad_alloc + CMemoryException, ...)

    Hi D_Drmmr,

    This is exactly what I've tried. I had put the link on top of the file newHandle.cpp

    http://msdn.microsoft.com/en-us/magazine/cc164087.aspx

    But it doesn't work. I've tried allowing memory in FOR loop and at a given time, the system displays a window that indicate "System memory very low". Then this window only allow you to click on an OK button that inevitably leads to a freeze the device OS.

    Someone else on another forum tell me that it is a normal condition, this is the responsability of the device OEM to remove or activate this window. Is that make sens ? If yes, then is there any way to desactivate it by code as we don't have the BSP code source ?

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Windows CE (STL + std::bad_alloc + CMemoryException, ...)

    Quote Originally Posted by Erakis View Post
    As my application must be robust, I need to test each memory allocation and in the case of an memory allocation failure . I want to be able to correctly clean the previously allocated resources.
    Nowhere in your sample are you calling operator new[] yourself.

    The flaw in your entire example is assuming that list::push_back() does what you think it does in terms of the C++ routines to allocate memory. Basically, if you don't see "new" or "new[]" called anywhere, you can't assume anything. What if the implementation uses malloc() and then placement-new? Wouldn't that bypass all of that code you have now, since placement-new doesn't really allocate anything? (all it does is place the pointer at the memory area that was malloc()-ed).

    Instead of this example, why not post a program that explicitly calls operator new[]? An example like this:

    http://msdn.microsoft.com/en-us/library/ms861441.aspx

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; November 15th, 2012 at 09:15 PM.

  5. #5
    Join Date
    Mar 2005
    Posts
    11

    Re: Windows CE (STL + std::bad_alloc + CMemoryException, ...)

    Hi Paul,

    Whatever I'm using the vector by data value or I use a vector holding data pointer that I have to allocate manually using new or malloc, it gives the same result. The system display the memory low dialog and eventually freeze.

    It's just that I did not put the two examples in my previous post.

    Here is the second exemple :

    Code:
    #include <list>
    using namespace std;
    
    typedef struct _MyObject
    {
        int a[9999];
    } MyObject;
    
    int i = 0;
    MyObject* p = NULL;
    list<MyObject *> v;
    try
    {
        // Force failure
        for (; i < 999999; ++i)
        {
            p = new MyObject();
            v.push_back(p);
        }
    }
    catch(CMemoryException* er)
    {
        DEBUG_ALERT("CMemoryException !");
    }
    catch(std::bad_alloc& er)
    {
        DEBUG_ALERT("bad_alloc error !");
    }
    So, this is exactly the same problem

    Try by ourself and you will see...

    What I've found so far is this article from Microsoft (http://msdn.microsoft.com/en-us/library/ms911907.aspx) that indicate how control this low memory dialog. But even if I change the registry and go to not display it, is that it may remove some security necessary for the stability of Windows CE OS ?

    Martin

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Windows CE (STL + std::bad_alloc + CMemoryException, ...)

    Quote Originally Posted by Erakis View Post
    Hi Paul,

    Whatever I'm using the vector by data value or I use a vector holding data pointer that I have to allocate manually using new or malloc, it gives the same result. The system display the memory low dialog and eventually freeze.
    Let's start at a common baseline, and that is your system and the code given to you at the link I gave you.

    Please take the exact example posted at the link I gave you. Does it show the same issue? If it doesn't work, then we have something that has been posted at the Microsoft site that can be investigated. If the code does work, then there is something in your code that is different or causes different behaviour.

    I don't have Windows CE, so I can't test your code. What you should be doing is taking code that MS has given us on that site, and proving or disproving that the code there really works (assuming you have set up your project correctly, i.e. correct options for exception handling).

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; November 16th, 2012 at 12:26 PM.

  7. #7
    Join Date
    Mar 2005
    Posts
    11

    Re: Windows CE (STL + std::bad_alloc + CMemoryException, ...)

    Hi Paul,

    Great new, I've retried and it's well working. But only if I'm doign the allocation by myself. Ex :

    Code:
    #include "new.h"
    #include <list>
    using namespace std;
    
    typedef struct _MyObject
    {
        int a[9999];
    } MyObject;
    
    
    
    int handle_program_memory_depletion( size_t )
    {
        ::AfxThrowMemoryException();
    }
    
    _set_new_handler( handle_program_memory_depletion );
    _set_new_mode(1);
    
    
    int i = 0;
    list<MyObject *> v;
    try
    {
        // Force failure
        for (; i < 999999; ++i)
        {
            v.push_back(new MyObject ());
        }
    }
    catch(CMemoryException* er)
    {
        DEBUG_ALERT("CMemoryException !");
        // I get the wanted exception here (IT NOW WORKING !!!)
    }
    catch(std::bad_alloc& er)
    {
        DEBUG_ALERT("bad_alloc error !");
    }

    BUT, this is not working if I'm pushing the data by value. Ex :

    Code:
    #include "new.h"
    #include <list>
    using namespace std;
    
    typedef struct _MyObject
    {
        int a[9999];
    } MyObject;
    
    
    
    int handle_program_memory_depletion( size_t )
    {
        ::AfxThrowMemoryException();
    }
    
    _set_new_handler( handle_program_memory_depletion );
    _set_new_mode(1);
    
    
    int i = 0;
    MyObject mo;
    list<MyObject> v;
    try
    {
        // Force failure
        for (; i < 999999; ++i)
        {
            v.push_back(mo);
        }
    }
    catch(CMemoryException* er)
    {
        DEBUG_ALERT("CMemoryException !");
        // I never get this exception !!!
    }
    catch(std::bad_alloc& er)
    {
        DEBUG_ALERT("bad_alloc error !");
    }
    Are you agree with me that when I push_back the mo object in the vector, the MyObject copy constructor will be called to create a new MyObject and it will be a member of the new NODE internally created by the Vector.

    From what I've see in the xmemory file of the stl, the new NODE created by the vector is allocated using the NEW oeprator . However, the preceeding code doesn't call the handle_program_memory_depletion handler. Instead I still get the "System very low memory" and the system completely freeze.

    So, why the new_handler doesn't affect the stl ???

    Best regards,
    Martin
    Last edited by Erakis; November 19th, 2012 at 12:21 PM.

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Windows CE (STL + std::bad_alloc + CMemoryException, ...)

    Quote Originally Posted by Erakis View Post
    Are you agree with me that when I push_back the mo object in the vector, the MyObject copy constructor will be called to create a new MyObject and it will be a member of the new NODE internally created by the Vector.
    If you are not calling "new" or "new[]" yourself, none of what you've stated is guaranteed to occur. There is no guarantee that copy construction is done under the hood, since copy construction can (and will be) optimized away by the compiler.
    From what I've see in the xmemory file of the stl, the new NODE created by the vector is allocated using the NEW oeprator .
    The "new" operator is just that -- an operator. There is no guarantee that each call to "new" allocates memory from the OS. The memory allocation is controlled by the heap manager. It's the heap manager that ultimately controls the allocations.

    Secondly, as stated before, there is placement-new. This form of "new" does not allocate memory -- instead another allocation is called (usually malloc), and the pointer is pointed to this area of memory by placement-new. You didn't mention what form of "new" is being called. I remember that some of the STL containers for Visual C++ uses placement new.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; November 19th, 2012 at 12:34 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured