I write the code like the following,
// Note that the output object below functions like the C++'s cout. It's my own // implementation of displaying program information and it's insignificant here. try{ try{ //output<<"exhausting the heap"<<endl; int* p = new int(); while(p!=NULL){ p = new int(); } //output<<" heap exhausted"<<endl; } catch(...){ // never reaches here because I use the --force_new_nothrow // Even if I dont't use --force_new_nothrow, the program never // reaches here too... //output<<"heap exhausted. and received an exception"<<endl; } //output<<"now I throw an int"<<endl; throw int(); } catch(...){ // unfortunately, the program never reach here // I guess it's because the exception object is to be created on the heep // but the heap is already exhausted. // So how should I handle the exception when allocation fails occurs? // output some debug imformation //output<<"unkown exception"<<endl; } // never reaches here too... //output<<"end"<<endl; while(1);
Actually the originan code I wrote is more complated. The Exception obj I throw is a class, so is the allocation object type I use to exhaust the heap. I output the address of these object, under the conditions of exhausted heap and unexhausted respectively. I found there is an exception object created on the heap.
So could anyone tell me how to handle the exception when memory allocation fails occurs ?
Any advice? Or I have to give up the c++ exception handling because it's behavior is undesirable when I've run out of memory and throwing an exception at the same time?
Maybe see this: stackoverflow.com/.../can-new-throws-in-a-case-of-heap-corruption
Note that the link isn't so much about ability to throw exceptions when the heap is full, but if new is able to detect a corrupt heap and throw an exception to complain. And the answer to that is: all bets are off.
Sorry, I don't know what the ARM compiler does when implementing exceptions. If the heap is used or if it plays with the stack until it finally runs out of the final catch block.
Per Westermark, ----------------- "Sorry, I don't know what the ARM compiler does when implementing exceptions. If the heap is used or if it plays with the stack until it finally runs out of the final catch block"
I've tried using the constructor to trace the construction and to print the location of objects. The ARM compiler does use the heap when an exception is thrown. just like class Test{ Test(){ cout<"Test() at "<<this<<endl; } }; when Test t; throw t; I found that there were a temp object created on the stack, and an object created on the heap.
I read the iso c++ standard. It says, "A throw-expression initializes a temporary object, called the exception objec. ... ... The memory for the exception object is allocated in an unspecified way". So that's not strictly defined.
When the heap has been exhausted, the program may still run normally cause memory is just enough for use, but the allocator will not be able to allocate any memory. Then if other kind of exception occurs, the program will not be able to handle it and would just terminate. Although not too likely, there is chance for it to happen.
This issue is discussed in the documentation, ARM® Compiler toolchain v5.02 for µVision Using ARM C and C++ Libraries and Floating-Point Support: <infocenter.arm.com/.../CJAFAGBA.html> and <infocenter.arm.com/.../CJAGCBHE.html>
Scott,
You linked to empty pages...
The links are OK - the terminating ">" on the address is the problem...!
Thanks, scott! I get it. Re-implementing the three functions may solve my issue. I will check it out later. extern "C" void *__ARM_exceptions_buffer_init() extern "C" void *__ARM_exceptions_buffer_allocate(void *buffer, size_t size) extern "C" void *__ARM_exceptions_buffer_free(void *buffer, void *addr)
Sorry, the trailing > is not part of the URL. (Surrounding URLs with <> is how I was taught to write them -- apparently it confuses this fourm software. I'll try to modify my behaviour in the furture.)
any trailing punctuation on a URL confuses this forum software!
But it's not just this forum software; lots of forums which attempt to automatically detect URLs make this type of mistake - the safe rule is to always ensure that there is clear whitespace around a URL.
Thanks to scott, I include these code, the behavior becomes desirable.
// To initialize the exceptions system before main is entered, // we have to include the following function in the link. // __ARM_exceptions_init will be called before main and // init of any global variables extern "C" void __cxa_get_globals(void); extern "C" void __ARM_exceptions_init(void) { output<<"__ARM_exceptions_init()"<<endl; __cxa_get_globals(); } // this function is never called. To make __ARM_exceptions_buffer_init called, // we must include the symbol __ARM_exceptions_buffer_required extern "C" void __ARM_exceptions_buffer_required(){ output<<"__ARM_exceptions_buffer_required()"<<endl; return ; } //static int buf[20]; // simple re-definition, not necessary. I worte it just to trace the call of // functions // extern "C" void *__ARM_exceptions_buffer_init(){ // output<<"__ARM_exceptions_buffer_init()"<<endl; // return buf; // just to test the behavior // } // extern "C" void *__ARM_exceptions_buffer_allocate(void *buffer, size_t size){ // output<<"__ARM_exceptions_buffer_allocate()"<<endl; // // just to test the behavior when heap is exhausted // // no complicated management is required here! // return buf; // } // extern "C" void *__ARM_exceptions_buffer_free(void *buffer, void *addr){ // output<<"__ARM_exceptions_buffer_free()"<<endl; // return addr; // } // test code int main(void) { output<<" in main function "<<endl; try{ try{ output<<"exhausting the heap"<<endl; int* p = new int(); while(p!=NULL){ p = new int(); } output<<" heap exhausted"<<endl; } catch(...){ /* never reach here because I use the --force_new_nothrow */ output<<"heap exhausted. and received an exception"<<endl; } output<<"now I throw an int"<<endl; throw int(); } catch(char){ output<<"catch a char"<<endl; } catch(int ){ output<<"catch an int"<<endl; } catch(...){ // output some debug imformation output<<"unkown exception"<<endl; } output<<"end"<<endl; while(1); }
Here is the output : __ARM_exceptions_init() in main function exhausting the heap heap exhausted now I throw an int catch an int end
if I un-comment the three functions and the global buf in the code, the output then becomes: __ARM_exceptions_init() __ARM_exceptions_buffer_init() in main function exhausting the heap heap exhausted now I throw an int __ARM_exceptions_buffer_allocate() catch an int __ARM_exceptions_buffer_free() end
See Now
infocenter.arm.com/.../CJAFAGBA.htmlinfocenter.arm.com/.../CJAGCBHE.html