CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 19 of 19
  1. #16
    Join Date
    Apr 1999
    Posts
    27,449

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

    Quote Originally Posted by Erakis View Post
    From MSDN :

    On Windows Desktop, when the new operator failed a CMemoryException is thrown.
    The CMemoryException is an MFC class. Wherever you got this information from, it is pertaining strictly to MFC. There is no MFC in the original code you posted, except for CMemoryException, which is why it's strange - the code has no other MFC in it whatsoever, not even including any MFC header files. So how could this code have even compiled correctly?

    That's why it's important to post all your code -- the code you posted (minus the CMemoryException object which has no way of being compiled successfully) was a vanilla C++ program, due to that the rules of "vanilla" ANSI C++ are supposed to be put into action. Those rules include that "new" must throw a std::bad_alloc exception on failure. If your code is really an MFC program, then the answers you get would have been different, since MFC has overloaded the new operator to return a NULL.

    Even if the allocation was made on a PLACEMENT NEW, as the stl container would swell, he should allocate memory somewhere for his placement area. So if this operation fails, then my new_handler should be called. Not ?
    No. Using placement-new allocates no memory -- what if the memory allocation is really done by malloc(), calloc(), etc. or the library is smart enough to use an array for smaller objects and only allocate using one of those functions when the number of objects become larger? Those are not hooked into the set_new_handler() mechanism.

    The bottom line is this -- the only thing that is guaranteed is that the calls to "new" that you make explicitly are tracked. Otherwise, you're relying on behaviour that may change or may be different, depending on how the library is implemented, compiler options chosen, etc. Look at the Visual C++ 2008 version -- there is a placement new there, so your assumptions about what gets allocated would have been false.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; November 20th, 2012 at 02:11 PM.

  2. #17
    Join Date
    Apr 1999
    Posts
    27,449

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

    Quote Originally Posted by Erakis View Post
    From What I notice in the template code, there no PLACEMENT new elsewhere ? It is a regular NEW ? Thus, if the allocation failed, my new_handler was not supposed to be called ?
    You should have debugged into that call to new. What do you see when you debug inside of this call to "new"? Is there any place where the allocation failure is checked?

    So the question is really this -- is there actual memory available, even though that message box shows up? Then if that's the case, is the system in a stable state if asked to allocate even more memory, at least stable enough to return a NULL pointer back to the heap manager? If not, then it is the system failing you and not operator new (or underlying function, such as malloc()).

    Regards,

    Paul McKenzie

  3. #18
    Join Date
    Mar 2005
    Posts
    11

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

    Hi Paul,


    Quote Originally Posted by Paul McKenzie
    The CMemoryException is an MFC class. Wherever you got this information from, it is pertaining strictly to MFC. There is no MFC in the original code you posted, except for CMemoryException, which is why it's strange - the code has no other MFC in it whatsoever, not even including any MFC header files. So how could this code have even compiled correctly?
    Yes, the application is build using Visual Studio 2005 + MFC + STL for Windows CE and Windows Desktop (x32/x64).
    I thought you deduced by reading the message. "November 20th, 2012, 11:02 AM" ; My classes name are prefixed with MFC word.


    Quote Originally Posted by Paul McKenzie
    You should have debugged into that call to new. What do you see when you debug inside of this call to "new"? Is there any place where the allocation failure is checked?
    I've did the test using a vector and then here it is the code of the _Allocate function

    Code:
    		// TEMPLATE FUNCTION _Allocate
    template<class _Ty> inline
    	_Ty _FARQ *_Allocate(_SIZT _Count, _Ty _FARQ *)
    	{	// check for integer overflow
    	if (_Count <= 0)
    		_Count = 0;
    	else if (((_SIZT)(-1) / _Count) < sizeof (_Ty))
    		_THROW(std::bad_alloc, NULL);
    
    		// allocate storage for _Count elements of type _Ty
    		return ((_Ty _FARQ *)::operator new(_Count * sizeof (_Ty)));;
    	}
    When pression F11 (Step over) on this line, nothing more happen. This is a normal new.

    If I well understand what you said : On Windows CE, I don't have any way to force the STL to throw an exeption while memory allocation failed ?

    At least, the new_handler trick is well working on Windows CE, but only when I'm calling new operator on MY CODE.

    Quote Originally Posted by Paul McKenzie
    No. Using placement-new allocates no memory -- what if the memory allocation is really done by malloc(), calloc(), etc. or the library is smart enough to use an array for smaller objects and only allocate using one of those functions when the number of objects become larger? Those are not hooked into the set_new_handler() mechanism.
    I know what is a placement-new, but are you agree with me that before using a placement-new we usually reserve a memory block, static or dynamic. And in the case of the STL I highly doubt it reserves STATIC memory. It would not make sense, since their containers are know to be dynamic size.

    Ex :

    Quote Originally Posted by Paul McKenzie
    // Allocate dynamic memory
    BYTE* pbBuffer = new BYTE[256];

    // Set a INT pointer on this memory
    INT* pContextInt = (INT*)pbBuffer[0];

    // Use the placement-new and allocate a new INT at the first slot of the placement area
    INT* pIntFirst = new (&pContextInt[0]) INT;

    // Use the placement-new and allocate a new INT at the second slot of the placement area
    INT* pIntSecond = new (&pContextInt[1]) INT;

    ...

    // Free dynamic memory
    delete [] pbBuffer;
    In RED, it could be a malloc and if it was the case, you tell me that I don't have any way to force an exception throw while it failed ?

    However, in this case it is not a malloc, instead it is a purely new OPERATOR, thus when the memory allocation failed, it should use my new-handler function, no ?


    Quote Originally Posted by Paul McKenzie
    Otherwise, you're relying on behaviour that may change or may be different, depending on how the library is implemented, compiler options chosen, etc. Look at the Visual C++ 2008 version -- there is a placement new there, so your assumptions about what gets allocated would have been false.
    Is there any compiler options available to do what I need ? I see somewhere on the MSDN that I could link using the thrownew.obj, but does this also apply to Windows CE ? Because I cannot build my project with this obj, I get link error.

    Best regards,
    Martin

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

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

    Quote Originally Posted by Erakis View Post
    I thought you deduced by reading the message.
    The only thing to go by is what you posted. From the code you posted, either CMemoryException is your own home-made class, or it's the MFC class. Since there was no header defining CMemoryException, either conclusion is valid. Depending on which one it is, the answers you get will be completely different.

    Again, this is why missing or omitted header files lead to ambiguous or wrong answers.
    When pression F11 (Step over) on this line, nothing more happen. This is a normal new.
    The source code to operator new exists. I don't know about Windows CE, but every commercial version of Visual C++ comes with complete source code to the run-time library and other functions. I am able to step into "new" with Visual C++ 2008, and there you will see what is being done.
    At least, the new_handler trick is well working on Windows CE, but only when I'm calling new operator on MY CODE.
    Which is why you need to figure out whether that call to "new" is different than the one in your application. It must be different, since identical functions cannot do two different things, unless the function has a bug (an uninitialized variable, for example).
    I know what is a placement-new, but are you agree with me that before using a placement-new we usually reserve a memory block, static or dynamic. And in the case of the STL I highly doubt it reserves STATIC memory.
    STL has nothing to say about where the memory comes from. Nothing stops an implementation from getting memory for a big, preallocated memory pool, where the pool is where the STL containers get their memory from.

    As a matter of fact, if you take a look at the second template argument to vector<T,alloc>, it is the allocator that gets memory, and that memory can come from anywhere. You can even override it to get memory from the stack.

    Also, the std::list class from Visual Studio 2008 didn't allocate any memory for one object, as far as I can tell. It's as if the memory did come from static storage, and only when the number of items exhausts this space will it get it from the heap -- all perfectly valid. I'm speculating, since I did minimal debugging and investigation, and I didn't see any call to malloc(), new, etc. when creating one object on the list.

    You cannot assume anything in this world of C++. Just because a class does things dynamically doesn't necessarily mean "new" or "malloc" is called, and if they are, in the places you expect them to be called.
    However, in this case it is not a malloc, instead it is a purely new OPERATOR, thus when the memory allocation failed, it should use my new-handler function, no ?
    All of this is answered if you debug into "new", and I'm sure it can be done since the source code to the run-time is available (did you install the run-time source)?

    Regards,

    Paul McKenzie

Page 2 of 2 FirstFirst 12

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