Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. How to handle dynamic memory allocation failure
QtWS25 Last Chance

How to handle dynamic memory allocation failure

Scheduled Pinned Locked Moved C++ Gurus
35 Posts 8 Posters 26.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Meraj Ahmad Ansari
    wrote on 7 Jun 2011, 08:55 last edited by
    #1

    Hi All,

    How to handle dynamic memory allocation failures in Qt application. If i am allocating memory by using "new" operator and new failed then how to handle its failure.

    eg.
    @
    BorderLayout *layout = NULL;
    layout = new BorderLayout; // if new failed then will it return NULL or throw exception?
    if (NULL == layout)
    {
    // Log error
    return;
    }
    @

    I didn't find any allocation failure handling in Qt sample code.

    Will somebody guide me how to handle allocation failure error?
    Do i have to use "new (std::nothrow)"?

    Regards,
    Meraj Ahmad Ansari

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andre
      wrote on 7 Jun 2011, 09:03 last edited by
      #2

      There is not much you realistically can do to recover gracefully from such an error, other than crash, AFAIK.

      1 Reply Last reply
      0
      • H Offline
        H Offline
        HuXiKa
        wrote on 7 Jun 2011, 09:53 last edited by
        #3

        Have you read "this":http://lists.trolltech.com/qt-interest/2006-03/thread00887-0.html?

        If you can find faults of spelling in the text above, you can keep them.

        1 Reply Last reply
        0
        • T Offline
          T Offline
          thisisbhaskar
          wrote on 7 Jun 2011, 10:12 last edited by
          #4

          yes you can always use standard C++ exception handling if you want.. otherwise, let it just crash.

          1 Reply Last reply
          0
          • G Offline
            G Offline
            giesbert
            wrote on 7 Jun 2011, 10:21 last edited by
            #5

            Afaik, most modern compilers use the exception way for out of memory. If you don't like that you have to use the “new (std::nothrow)” notation.
            But handling std::out_of_memory is a bit difficult, because, what do you want to do then? Show a dialog? That also allocates memory. Write a log file? same issue....

            Nokia Certified Qt Specialist.
            Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

            1 Reply Last reply
            0
            • M Offline
              M Offline
              Meraj Ahmad Ansari
              wrote on 7 Jun 2011, 15:50 last edited by
              #6

              @Gerolf: If memory allocation failed then i want to gracefully shutdown my app.

              1 Reply Last reply
              0
              • M Offline
                M Offline
                Meraj Ahmad Ansari
                wrote on 7 Jun 2011, 15:54 last edited by
                #7

                I think its time to reformulate question- I have some code, guys are initializing pointers by NULL, allocating memory and then they are checking that memory allocation failed or not by comparing pointer with NULL.
                Please check following code -
                @
                CSomeClass* p = NULL;
                p = new CSomeClass;
                if ( NULL != p ) // Is this check relevent???
                {
                // do something
                }
                @

                i think above check does not have any relevence.
                There app is not crashing(by good luck). During code review i found this check useless and their claim is that their memory allocation code is OK.

                So I just want to clarify my doubt as i think we can not assume something during development.

                1 Reply Last reply
                0
                • K Offline
                  K Offline
                  koahnig
                  wrote on 7 Jun 2011, 16:10 last edited by
                  #8

                  To my understanding it is common practice to the pointer for proper assignment.
                  One reason could be that new does not stop the application and simply returns a Null pointer. This is certainly possible if someone writes his/her own new operator.

                  [quote author="Gerolf" date="1307442082"]
                  But handling std::out_of_memory is a bit difficult, because, what do you want to do then? Show a dialog? That also allocates memory. Write a log file? same issue....[/quote]

                  I guess std::out_of_memory means usual cases. If you just try allocate a couple of bytes, you are certainly right. However, if by any wrong input the size to be allocated is outside of your standard sizes, you have and may be you want to have the chance to react on the failure.

                  Vote the answer(s) that helped you to solve your issue(s)

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    koahnig
                    wrote on 7 Jun 2011, 16:21 last edited by
                    #9

                    Here is also some reference showing that not only exotic compilers may return a Null.
                    http://msdn.microsoft.com/en-us/library/kftdy56f(v=vs.71).aspx

                    So I guess it is still good practice to check the return value

                    Vote the answer(s) that helped you to solve your issue(s)

                    1 Reply Last reply
                    0
                    • G Offline
                      G Offline
                      giesbert
                      wrote on 7 Jun 2011, 18:51 last edited by
                      #10

                      The point is, it is possible to use no throw new, but by default, MSVS uses throwing new

                      bq. Beginning in Visual C++ .NET 2002, the CRT's new function (in libc.lib, libcd.lib, libcmt.lib, libcmtd.lib, msvcrt.lib, and msvcrtd.lib) will continue to return NULL if memory allocation fails. However, the new function in the Standard C++ Library (in libcp.lib, libcpd.lib, libcpmt.lib, libcpmtd.lib, msvcprt.lib, and msvcprtd.lib) will support the behavior specified in the C++ standard, which is to throw a std::bad_alloc exception if the memory allocation fails.

                      Nokia Certified Qt Specialist.
                      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                      1 Reply Last reply
                      0
                      • K Offline
                        K Offline
                        koahnig
                        wrote on 7 Jun 2011, 19:06 last edited by
                        #11

                        Yes, I understand, but a little further down you will find also:

                        (4th paragraph) "Even if you use one of the C++ standard library headers, it is possible to get non-throwing new. For example, compile the program below with the following command line and you will not get throwing new behavior, even though standard C++ header files are included: "

                        So either you restrict the user not to use /EHsc switch or you should be prepared.

                        PS: I am wondering why the "quote" button does not work anymore :-(

                        Vote the answer(s) that helped you to solve your issue(s)

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          Meraj Ahmad Ansari
                          wrote on 8 Jun 2011, 07:09 last edited by
                          #12

                          Only point is it -if you are using new( no std::nothrow functionality) and after allocation checking its return value to NULL. Is it valid ?
                          If we are not using std::nothrow then it will not return NULL and subsequent call will crash. But if we are using std::nothrow and checking NULL then developer can take preventive actions(eg. gracefully shutdown).

                          1 Reply Last reply
                          0
                          • K Offline
                            K Offline
                            koahnig
                            wrote on 8 Jun 2011, 07:35 last edited by
                            #13

                            To my understanding, yes.
                            With checking the pointer for its return value you are more on the save side. You are independent of the actual default setting of your compiler. Also in case someone is changing some switches as possible with the ms compiler, you should be save. However, in case of new with throwing option, you might want to add the functionality catching the out of memory event. This allows you in such cases a graceful shutdown.

                            Ultimatively, one needs to decide to wear your pants with a belt, with suspenders or with both. ;-)

                            Vote the answer(s) that helped you to solve your issue(s)

                            1 Reply Last reply
                            0
                            • L Offline
                              L Offline
                              lgeyer
                              wrote on 8 Jun 2011, 08:30 last edited by
                              #14

                              [quote author="Gerolf" date="1307442082"]But handling std::out_of_memory is a bit difficult, because, what do you want to do then? Show a dialog? That also allocates memory. Write a log file? same issue....[/quote]

                              There is one thing you can actually do in applications that absolutely have to shutdown gracefully - request a block of memory at startup which serves as an "emergency heap" in case you run out of memory during runtime and use "placement new":http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10 or - if you need support for creating Qt objects too - "custom global allocators":http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14.

                              Thus you can still create objects on the heap including a nifty QMessageBox if you want to.

                              1 Reply Last reply
                              0
                              • G Offline
                                G Offline
                                giesbert
                                wrote on 8 Jun 2011, 08:43 last edited by
                                #15

                                [quote author="Meraj Ahmad Ansari" date="1307516970"]Only point is it -if you are using new( no std::nothrow functionality) and after allocation checking its return value to NULL. Is it valid ?
                                If we are not using std::nothrow then it will not return NULL and subsequent call will crash. But if we are using std::nothrow and checking NULL then developer can take preventive actions(eg. gracefully shutdown).[/quote]

                                It is not possible that new returns something else than 0 if it can't allocate memory.

                                return 0

                                throw exception (nothing is returned, variable is not changed)

                                If it is throwing, you will not continue as usual, as you have to catch the exception.

                                Nokia Certified Qt Specialist.
                                Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                                1 Reply Last reply
                                0
                                • A Offline
                                  A Offline
                                  andre
                                  wrote on 8 Jun 2011, 09:03 last edited by
                                  #16

                                  [quote author="Lukas Geyer" date="1307521825"][quote author="Gerolf" date="1307442082"]But handling std::out_of_memory is a bit difficult, because, what do you want to do then? Show a dialog? That also allocates memory. Write a log file? same issue....[/quote]

                                  There is one thing you can actually do in applications that absolutely have to shutdown gracefully - request a block of memory at startup which serves as an "emergency heap" in case you run out of memory during runtime and use "placement new":http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10 or - if you need support for creating Qt objects too - "custom global allocators":http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14.

                                  Thus you can still create objects on the heap including a nifty QMessageBox if you want to.[/quote]

                                  Very interesting idea, but are you sure it would work? I mean: new-ing a messagebox will not just create that message box, but the message box in turn will new other (child) objects. You have no control over how that happens; there is no way you can use placement new or something like that for it, I think? You may be able to write a message into a logfile manually or something like that, but I doubt you could do much more than that. Still, the solution is certainly interesting!

                                  1 Reply Last reply
                                  0
                                  • M Offline
                                    M Offline
                                    Meraj Ahmad Ansari
                                    wrote on 8 Jun 2011, 10:44 last edited by
                                    #17

                                    bq. @koahnig; ....Also in case someone is changing some switches as possible with the ms compiler,.....

                                    I only want to discuss it under gcc (QtCreator). Does QtCreator support switches? No doubt Visual Studio is really great

                                    bq. @Gerolf : If it is throwing, you will not continue as usual, as you have to catch the exception.

                                    currently my code base is very large and unfortunately with out exception handling and that is why i am thinking about std::nothrow

                                    Thanks to all guys for your support.

                                    1 Reply Last reply
                                    0
                                    • K Offline
                                      K Offline
                                      koahnig
                                      wrote on 8 Jun 2011, 11:32 last edited by
                                      #18

                                      [quote author="Meraj Ahmad Ansari" date="1307529893"]bq. @koahnig; ....Also in case someone is changing some switches as possible with the ms compiler,.....

                                      I only want to discuss it under gcc (QtCreator). Does QtCreator support switches? No doubt Visual Studio is really great
                                      [/quote]
                                      I am not an expert on QtCreator, but almost everything can be changed on the project's tap. Unfortunately, you have to dig sometimes into the details of a couple of tools.

                                      Vote the answer(s) that helped you to solve your issue(s)

                                      1 Reply Last reply
                                      0
                                      • L Offline
                                        L Offline
                                        lgeyer
                                        wrote on 8 Jun 2011, 12:55 last edited by
                                        #19

                                        [quote author="Andre" date="1307523827"]
                                        [quote author="Lukas Geyer" date="1307521825"]
                                        There is one thing you can actually do in applications that absolutely have to shutdown gracefully - request a block of memory at startup which serves as an "emergency heap" in case you run out of memory during runtime and use "placement new":http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10 or - if you need support for creating Qt objects too - "custom global allocators":http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.14.

                                        Thus you can still create objects on the heap including a nifty QMessageBox if you want to.[/quote]

                                        Very interesting idea, but are you sure it would work? I mean: new-ing a messagebox will not just create that message box, but the message box in turn will new other (child) objects. You have no control over how that happens; there is no way you can use placement new or something like that for it, I think? You may be able to write a message into a logfile manually or something like that, but I doubt you could do much more than that. Still, the solution is certainly interesting!

                                        [/quote]

                                        I initially came up with three solutions:

                                        Reserve a bunch of memory at startup and release it when neccessary to gain memory

                                        Reserve a bunch of memory at startup and use it directly as "heap replacement" using placement new

                                        Reserve a bunch of memory at startup and use it directly as "heap replacement" by overloading the global new operator or setting a new handler using std::set_new_handler

                                        It would not prefer 1. because you cannot guarantee that the operating system will return the memory you just freed back to your application (most likely it won't if free memory is rare).

                                        I prefer 2., which usually works flawlessly, provided that your allocation code does so (keyword memory alignment) ;-)

                                        I personally never used 3., because if you usually run out of memory your system is thrashing anyways long before and the application should shut down as soon as possible (without any user interaction). Nevertheless it should work by replacing the global operator new with your own memory management code which can switch between system memory and "emergency memory".

                                        @
                                        // class.h
                                        #ifndef CLASS_H
                                        #define CLASS_H

                                        class Class
                                        {
                                        public:
                                        Class();
                                        };

                                        #endif // CLASS_H

                                        // class.cpp
                                        #include "class.h"

                                        Class::Class()
                                        {
                                        int* pointer = new int;
                                        }

                                        // main.cpp
                                        #include "class.h"

                                        void* operator new(size_t size)
                                        {
                                        // Implementation goes here
                                        }

                                        void operator delete(void* pointer)
                                        {
                                        // Implementation goes here
                                        }

                                        int main(int argc, char argv[])
                                        {
                                        Class
                                        pointer = new Class;

                                        return 0;
                                        

                                        }
                                        @

                                        Executing the example above shows that both situations are handled correctly (the custom global new operator is called twice); creating objects outside and inside classes.

                                        Setting a new handler using std::set_new_handler which should be called in case of no-new-memory-situations should do the same trick, as it is allowed to either throw an bad_alloc exception or terminate the application or allocating and returning memory somewhere else, for example at our "emergency heap". I think this is the preferred solution for 3. (when having no global / static objects, where you cannot guarantee that std::set_new_handler has been already executed), as you do not have to mess with the global new operator.

                                        Please keep also in mind, that even if new is returning a valid pointer (not returning null) this does not mean that there is actually memory available for the application. If I remember correctly new on Linux systems always returns a valid pointer, as memory is acquired on access, not on allocation!

                                        So the following snippet will crash even due to proper error handling
                                        @
                                        int* integer = new int;
                                        if(integer != 0)
                                        {
                                        *integer = 42; // crash
                                        }
                                        @

                                        Question is, does the runtime call the function set by std::set_new_handler in this case? Never tried that.

                                        1 Reply Last reply
                                        0
                                        • K Offline
                                          K Offline
                                          koahnig
                                          wrote on 8 Jun 2011, 13:22 last edited by
                                          #20

                                          [quote author="Lukas Geyer" date="1307537741"]
                                          Please keep also in mind, that even if new is returning a valid pointer (not returning null) this does not mean that there is actually memory available for the application. If I remember correctly new on Linux systems always returns a valid pointer, as memory is acquired on access, not on allocation!

                                          So the following snippet will crash even due to proper error handling
                                          @
                                          int* integer = new int;
                                          if(integer != 0)
                                          {
                                          *integer = 42; // crash
                                          }
                                          @

                                          Question is, does the runtime call the function set by std::set_new_handler in this case? Never tried that.[/quote]

                                          But what sense would the check of the pointer make then?

                                          BTW: Is it just in my browser that the last paragraph after the example is NOT shown in the original post?
                                          I just came across it when quoting the post.

                                          Vote the answer(s) that helped you to solve your issue(s)

                                          1 Reply Last reply
                                          0

                                          2/35

                                          7 Jun 2011, 09:03

                                          topic:navigator.unread, 33
                                          • Login

                                          • Login or register to search.
                                          2 out of 35
                                          • First post
                                            2/35
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved