2012-01-15 32 views
11

मैं अपने आवेदन में कुछ गंभीर मेमोरी लीक में चल रहा है, इसलिए मैं सेटअप के परीक्षण हेतु क्या होता है जब एक स्ट्रिंग सरणी दायरे से बाहर चला जाता है यह अत्यंत नंगे समाधान पर पुनः आवंटित की जाती नहीं ...स्ट्रिंग सरणी दायरे से बाहर निकलें

मुझे पता है स्ट्रिंग के पुराने टेक्स्टस्ट्रिंग कार्यान्वयन में विनाशक की कमी थी, लेकिन इस वर्तमान कार्यान्वयन में ऐसा लगता है।

मैं this MemoryFree library (का उपयोग कर रहा हूं नोट करें कि इस लिंक किए गए कोड को अब इस प्रश्न के स्वीकृत उत्तर के आधार पर तय किया गया है)।

कोड दो परिदृश्यों की जांच करता है: दो अलग-अलग कार्यों में चार सरणी और स्ट्रिंग सरणी का आवंटन दोनों पर दायरे से बाहर निकलने के लिए मजबूर करता है।

#include <MemoryFree.h> 

void setup() { 
    // put your setup code here, to run once: 
    Serial.begin(9600); 
    int freeBefore, freeAfter; 

    //TEST ALLOCATION OF CHAR ARRAY// 
    freeBefore = freeMemory(); 
    AllocateCharArr(); 
    freeAfter = freeMemory(); 
    Serial.println("CHAR*: Before " + String(freeBefore) 
    + ", After " + String(freeAfter) 
    + ", Diff " + String(freeBefore - freeAfter)); 

    //TEST ALLOCATION OF STRING// 
    freeBefore = freeMemory(); 
    AllocateStringArr(); 
    freeAfter = freeMemory(); 
    Serial.println("STRING: Before " + String(freeBefore) 
    + ", After " + String(freeAfter) 
    + ", Diff " + String(freeBefore - freeAfter)); 
} 

void AllocateCharArr() { 
    char s[100]; 
} 

void AllocateStringArr() { 
    String s[100]; 
} 

void loop() { /* empty */ } 

आउटपुट:

CHAR *: 1710 से पहले, 1710 के बाद Diff 0
STRING: 1645 से पहले, 1309 के बाद, Diff 336

कैसे String सरणी आवंटन आ स्मृति से मिटा नहीं है?

+1

परिणाम क्या है जब 'स्ट्रिंग' सरणी बहुत छोटे (जैसे 10 तत्वों) है? – ouah

+0

दिलचस्प: 50 तत्व = diff 136, 25 तत्व = diff 36, 10 तत्व = diff 0 –

+0

क्या आप Arduino सॉफ़्टवेयर का उपयोग कर रहे हैं (0023, 1.0, ...)? –

उत्तर

4

String कक्षा (see forum post here) का परीक्षण करते समय 1.0 से पहले Arduino संस्करणों में मेमोरी हैंडलिंग समस्याओं में आया है।

स्ट्रिंग निर्माता आंतरिक realloc का उपयोग करता है और यह इस (AVR libc) गतिशील स्मृति से निपटने कि समस्याओं (ढेर __brkvalfree() पर अद्यतन नहीं किया जा रहा के शीर्ष करने के सूचक के कारण) के कारण किया गया है।

भागो Arduino 1.0 में संस्करणों 0023, 0022, आदि में इन मुद्दों को देखने के लिए कोड कोई स्मृति लीक दिखाना चाहिए निम्नलिखित कोड:

#if (ARDUINO >= 100) 
#include <Arduino.h> 
#else 
#include <WProgram.h> 
#endif 
#include <HardwareSerial.h> 
#include <MemoryFree.h> 

void setup() { 
    // put your setup code here, to run once: 
    Serial.begin(9600); 
    int freeBefore, freeAfter; 

    freeBefore = freeMemory(); 

    void* buffer = malloc(10); 
    if (buffer == 0) { 
    Serial.println("Failed to allocate memory"); 
    } 
    free(buffer); 

    freeAfter = freeMemory(); 
    Serial.println("Before " + String(freeBefore) 
    + ", After " + String(freeAfter) 
    + ", Diff " + String(freeBefore - freeAfter)); 
} 

void loop() { 
} 

इसके अलावा, आप उपयोग कर रहे हैं MemoryFree पुस्तकालय गलत दे सकते हैं नतीजे क्योंकि यह मुफ्त सूची में ध्यान नहीं देता है। MemoryFree.cpp के इस अद्यतन संस्करण का प्रयास करें:

extern unsigned int __heap_start; 
extern void *__brkval; 

/* 
* The free list structure as maintained by the 
* avr-libc memory allocation routines. 
*/ 
struct __freelist { 
    size_t sz; 
    struct __freelist *nx; 
}; 

/* The head of the free list structure */ 
extern struct __freelist *__flp; 

#include "MemoryFree.h"; 

/* Calculates the size of the free list */ 
int freeListSize() { 
    struct __freelist* current; 
    int total = 0; 

    for (current = __flp; current; current = current->nx) { 
    total += 2; /* Add two bytes for the memory block's header */ 
    total += (int) current->sz; 
    } 

    return total; 
} 

int freeMemory() { 
    int free_memory; 

    if ((int)__brkval == 0) { 
    free_memory = ((int)&free_memory) - ((int)&__heap_start); 
    } else { 
    free_memory = ((int)&free_memory) - ((int)__brkval); 
    free_memory += freeListSize(); 
    } 
    return free_memory; 
} 
+0

धन्यवाद! यह पता चला कि यह फ्रीमेमरी फ़ंक्शन था जिसने खराब मूल्यों की सूचना दी थी। इसके बजाए आपकी आपूर्ति विधि का उपयोग करके, सही परिणाम मिलते हैं और कोई रिसाव नहीं होता है। –

+0

Arduino 1.0 पुस्तकालयों को जानना अच्छा है ठीक है। जवाब अपडेट करेंगे। धन्यवाद! –

+0

मैंने इस स्वीकृत उत्तर के साथ Arduino साइट (http://arduino.cc/playground/Code/AvailableMemory) पर MemoryFree.cpp लाइब्रेरी कोड अपडेट किया है। –

0

यदि आप Arduino source देखते हैं, तो आप फ़ाइल भर सकते हैं "। \ Arduino-1.0 \ हार्डवेयर \ arduino \ cores \ arduino \ WString.cpp"। इस फ़ाइल में, मैंने देखा है कि स्ट्रिंग में डिफ़ॉल्ट (पैरामीटर रहित) कन्स्ट्रक्टर नहीं है। शायद यह समस्या हो सकती है? संदिग्ध, लेकिन वैसे भी, स्रोत मदद चाहिए। शुभकामनाएँ।

+0

मैं पहले से ही उस फाइल को देख रहा हूं, मुख्य रूप से यह सत्यापित करने के लिए कि इसमें एक विनाशक था। मैं यह देखने के लिए परीक्षण करूंगा कि मूल्यों के साथ शुरू की गई सरणी में कोई फर्क पड़ता है या नहीं। –

0

String s[100]; लाइन पर टिप्पणी करें और देखें कि क्या आपको अलग-अलग परिणाम मिलते हैं। ऐसा लगता है कि आपके द्वारा देखे जा रहे मेमोरी आवंटन setup() फ़ंक्शन में स्ट्रिंग ऑपरेशंस के कारण हैं, AllocateStrArr() में तारों की स्थानीय सरणी की घोषणा के लिए नहीं। WString.cpp और WString.h पर यह देखने के लिए कि operator+ पर ओवरराइड किया गया है, इसलिए String() पर प्रत्येक कॉल या + का उपयोग करके समामेलन एक और ऑब्जेक्ट बना सकता है।

+0

उस पंक्ति पर टिप्पणी करते हुए यह 0 –

संबंधित मुद्दे