[英]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(),所以我的想法是從當前上下文“轉義”並進入無限循環
對不起,我的英語不好
因此,如果您想退出某個函數並回到原來的位置,則應該離開該函數,而不要調用原始函數! 通過從函數返回,或使用setjmp
和longjmp
。
並且在所有情況下,您還需要擔心“如何清理數據”。 換句話說,如果您分配了內存,則需要在離開函數之前釋放它,例如,打開了文件,需要關閉文件等。
RAII原理非常有用,但是它假定您將函數留在編譯器的知識范圍之內,而不是只是跳回主循環而不進行清理。 遲早會引起問題。
還要注意,堆棧溢出的行為是未定義的行為-可能會立即使程序崩潰,或者可能導致堆被覆蓋,格式化硬盤驅動器/ SD卡,或者可能導致守護程序從您的鼻子里飛出來。 或您可能想到的其他任何東西,然后再說一些。 它是未定義的,您不能依靠它做任何特別的事情-只是“您不應該這樣做”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.