Arduino C कोड में मेमोरी ओवरफ्लो त्रुटियों की खोज कैसे करें?


10

कई बार मेरे पास Arduino पर कोड अपलोड करने के बाद सीरियल मॉनीटर पर कुछ संदिग्ध आउटपुट थे: जैसे कि व्हॉट्सएप का शाश्वत आउटपुट या अचानक स्ट्रिंग्स या तले हुए स्ट्रिंग्स का कट।

क्योंकि Arduino IDE में कोई संकलित त्रुटि या चेतावनी नहीं थी, मुझे लगा कि Arduino टूट गया है, लेकिन कुछ परीक्षणों के बाद मुझे पता चला कि Arduino IDE संकलक द्वारा सभी प्रकार की त्रुटियों को नहीं पकड़ा गया है - खासकर जब सरणी संरचनाओं के लिए एक लूप में चर असाइन करना। यह कुछ ही समय में Arduino को क्रैश कर देता है।

मैं Arduino IDE द्वारा प्रदर्शित त्रुटियों को कैसे खोज सकता हूं?

जवाबों:


10

MemoryFree पुस्तकालय आप स्मृति के उपयोग के साथ जोखिम को खोजने में मदद कर सकते हैं।

उदाहरण:

#include <MemoryFree.h>

// On Arduino Duemilanove with ATmega328:
//
// Reported free memory with str commented out:
// 1824 bytes
//
// Reported free memory with str and Serial.println(str) uncommented:
// 1810
//
// Difference: 14 bytes (13 ascii chars + null terminator)

// 14-bytes string
//char str[] = "Hello, world!";


void setup() {
    Serial.begin(115200);
}


void loop() {
    //Serial.println(str);

    Serial.print("freeMemory()=");
    Serial.println(freeMemory());

    delay(1000);
}

मैमोरीफ्री स्टैक पॉइंटर के लिए खाता है तो मैं अनिश्चित हूं। यदि आपका स्टैक पॉइंटर आपके हीप पॉइंटर से टकराता है तो आप विभाजन दोष का अनुभव कर सकते हैं।


7

रैम थकावट का सबसे आम कारण स्ट्रिंग ऑब्जेक्ट का उपयोग करना या बहुत सारे निरंतर-चरित्र सरणियों (सी-स्टाइल स्ट्रिंग) का उपयोग करना है।

IDE 1.0.4 में फोर्सटॉक के लिए एक फिक्स शामिल है जिसने बहुत लंबे समय तक स्ट्रिंग-ऑब्जेक्ट को नुकसान पहुंचाया है।

निरंतर-वर्ण स्ट्रिंग्स द्वारा बर्बाद की गई रैम को कम करने के लिए जैसे:

Serial.print("Hello World");  // This consumes RAM!

आप F () मैक्रो का उपयोग कर सकते हैं। यह मैक्रो चरित्र सरणी PROGMEM में रहने के लिए मजबूर करेगा। जब सरणी का उपयोग किया जाता है, तो मेमोरी का केवल एक बाइट खपत होता है।

Serial.print(F("Hello World"));  // Keeps the character-array in PROGMEM

ध्यान रखें कि PROGMEM में संग्रहीत तार को रनटाइम के दौरान परिवर्तित नहीं किया जा सकता है।

जहाँ तक खोज है, डिबगर या मेमोरी कंट्रोलर के बिना, आपको पुरानी समस्याओं का पता लगाने के लिए पुराने जमाने की जासूसी तकनीकों का उपयोग करना होगा।


1
उपयोगी उत्तर के लिए धन्यवाद! वास्तव में कोई आईडीई सपोर्ट मेमोरी डिबगर नहीं है?
पौव्वक

1
यह एक पुराना प्रश्न है, लेकिन हाँ, Atmel ATmega MCUs के लिए उचित डिबगर्स हैं। Arduino के लिए कोई डीबगर्स नहीं हैं , क्योंकि Arduino टूलकिन और "IDE" मूल रूप से एक खिलौना है।
कॉनर वुल्फ

1
वास्तव में एफ () के साथ आपके संकेत ने हमें रैम में कुछ सौ बाइट्स बचाए!
powtac

1
F () वाले स्ट्रिंग्स का उपयोग करते समय मुझे एक संकलन त्रुटि मिलती है //। :-(
powtac

मुझे यह संकलित त्रुटि Arduino 1.5.7 पर मिली ...
powtac

3

ऐसा लगता है कि आप यहां रनटाइम त्रुटियों (मेमोरी लीक / सेगफॉल्ट प्रकार) के बारे में बात कर रहे हैं।

इस तरह की त्रुटियों को खोजने का कोई तरीका नहीं है (जब तक कि आप कोड के माध्यम से बहुत सावधानी से कंघी न करें) कोड में पहले से ही लिखा है। हालाँकि, कोड लिखते समय इन्हें होने से रोकना काफी आसान है । छोरों या पुनरावर्ती कॉल लिखते समय बस बहुत सावधान रहें; अपने आप से पूछें "क्या यह हाथ से निकल सकता है?"। यदि ऐसा लगता है कि यह "हाथ से बाहर निकलने" की गुंजाइश है, तो उस से बचाने के लिए कोड लिखें।

Segfaults के बारे में - बस सरणी सूचकांकों के सीमा मानों की जांच करें और आपको ठीक होना चाहिए। यदि आप पॉइंटर्स का उपयोग कर रहे हैं, तो कृपया पॉइंटर अंकगणित से सावधान रहें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.