简体   繁体   中英

Arduino memory types, academic

Dear Stackoverflow Users,

I have an interesting question and I wish to hear your opinions out, also please correct me at any part.

In a normal PC the memory adresses splits into 3 parts, stack, heap, globals, (lets forget peripherials now), so if I go ahead and make a bad recursive function which fills the stack with calls, the OS will send a message of stackoverflow, also if I make an infinite loop with a new keyword in it, it'll fill the heap with junk data, and get something like segfault, but what if I make such mistakes in an arduino project?

try / catch blocks are out of the game, so I tried to make my own realization of error handling in loop(), abusing the stupidity of the preprocessor:

#define THROW(errval)       \
ERROR = errval;             \
loop()

#define TRY                 \
if(ERROR == 0)

#define CATCH(err)              \
else if(err == ERROR)

#define FINALLY                 \
if(ERROR != 0)

#define OUT_OF_MEMORY 1    

int ERROR = 0;

void random_routine() {
    if(/*something goes wrong*/) {
        THROW(OUT_OF_MEMORY);
    }
}

void start() { Serial.begin(9600); }
void loop() {
    TRY {
        random_routine();
    } CATCH(OUT_OF_MEMORY) {
        Serial.println("out of memory");
    } FINALLY {
        while(true);
    }
}

Now you might not see the trick here instantly so this is what you get after the preprocessing:

void random_routine() {
     if(/*something goes wrong*/) {
          ERROR = 1;
          //this call is the body of my exception handling solution
          //and the question is about this as well
          loop();
     }
}
void start() { Serial.begin(9600); }
void loop() {
     ///TRY-s macro result
     if(ERROR == 0) {
         random_routine();
     ///chainable CATCH blocks
     } else if(ERROR == 1) {
         Serial.println("Out of memory");
     }
     ///FINALLY block
     if(ERROR != 0) {
         while(true);
     }
}

So my question is, what if the memory gets full for some reason, will a function call be able to get executed? Because the THROW macro will always call loop() that way my idea to 'escape' from the current context and get into an infinite loop

Sorry for my bad english

So, if you want to exit a function and get back to where you came from, you should leave the function, not call the original function! Either by returning from the function, or use setjmp and longjmp .

And in all cases, you also need to worry about "how does data get cleaned up". In other words, if you allocate memory, then you need to free it before leaving the function, of you have opened a file, you need to close it, etc.

These sort of things is where the RAII principle comes in very handy, but it assumes you leave the function under the knowledge of the compiler, and not that you just jump back to your main loop without cleaning up. It will sooner or later cause problems.

Note also that the behaviour with stack overflow is UNDEFINED BEHAVIOUR - it MAY crash the program immediately, or it may cause the heap to be overwitten, format your harddrive/SD Card, or it may cause daemons to fly out of your nose. Or anything else you can possibly imagine and then some. It is undefined, you can't rely on it doing anything in particular - just that "you're not supposed to do that".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM