繁体   English   中英

Arduino内存类型,学术

[英]Arduino memory types, academic

尊敬的Stackoverflow用户,

我有一个有趣的问题,希望听到您的意见,也请随时纠正我。

在普通PC中,内存地址分为3个部分:堆栈,堆,全局变量(现在让我们忘记外围设备),因此,如果我继续执行一个不好的递归函数,使调用充满了堆栈,则操作系统将发送一条消息stackoverflow,如果我使用新的关键字进行无限循环,它也会用垃圾数据填充堆,并得到segfault之类的东西,但是如果我在arduino项目中犯了这样的错误怎么办?

try / catch块不在游戏之列,因此我尝试在loop()中实现错误处理的自己的实现,从而滥用了预处理器的愚蠢性:

#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);
    }
}

现在您可能不会立即在此处看到窍门,因此这是经过预处理后得到的结果:

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);
     }
}

所以我的问题是,如果由于某种原因内存已满,该函数调用将能够执行吗? 因为THROW宏将始终以这种方式调用loop(),所以我的想法是从当前上下文“转义”并进入无限循环

对不起,我的英语不好

因此,如果您想退出某个函数并回到原来的位置,则应该离开该函数,而不要调用原始函数! 通过从函数返回,或使用setjmplongjmp

并且在所有情况下,您还需要担心“如何清理数据”。 换句话说,如果您分配了内存,则需要在离开函数之前释放它,例如,打开了文件,需要关闭文件等。

RAII原理非常有用,但是它假定您将函数留在编译器的知识范围之内,而不是只是跳回主循环而不进行清理。 迟早会引起问题。

还要注意,堆栈溢出的行为是未定义的行为-可能会立即使程序崩溃,或者可能导致堆被覆盖,格式化硬盘驱动器/ SD卡,或者可能导致守护程序从您的鼻子里飞出来。 或您可能想到的其他任何东西,然后再说一些。 它是未定义的,您不能依靠它做任何特别的事情-只是“您不应该这样做”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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