2012-01-15 27 views
11

Tôi đang chạy vào một số rò rỉ bộ nhớ nghiêm trọng trong ứng dụng của tôi, vì vậy tôi thiết lập giải pháp cực kỳ trần này để kiểm tra những gì sẽ xảy ra khi một mảng chuỗi đi ra khỏi phạm vi ...Chuỗi mảng không deallocated trên phạm vi thoát

tôi biết rằng việc thực thi TextString cũ của String thiếu một hàm hủy, nhưng việc triển khai hiện tại này dường như có nó.

Tôi đang sử dụng this MemoryFree library (Lưu ý mã được liên kết này hiện đã được khắc phục dựa trên câu trả lời được chấp nhận cho câu hỏi này).

Mã kiểm tra hai kịch bản: Phân bổ mảng char và mảng chuỗi trong hai hàm khác nhau để buộc thoát khỏi phạm vi trên cả hai.

#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 */ } 

Output:

CHAR *: Trước 1710, Sau 1710, Diff 0
STRING: Trước năm 1645, Sau 1309, Diff 336

Làm thế nào đến việc phân bổ String mảng không bị xóa khỏi bộ nhớ?

+1

kết quả là gì khi 'chuỗi' mảng nhỏ hơn nhiều (ví dụ, 10 phần tử)? – ouah

+0

Thú vị: 50 phần tử = khác 136, 25 phần tử = khác 36, 10 phần tử = khác 0 –

+0

Phiên bản phần mềm Arduino nào bạn đang sử dụng (0023, 1.0, ...)? –

Trả lời

4

Tôi đã gặp các vấn đề xử lý bộ nhớ trong các phiên bản Arduino trước 1.0 khi kiểm tra lớp String (see forum post here).

Trình tạo chuỗi sử dụng realloc nội bộ và xử lý bộ nhớ động (avr libc) đã gây ra sự cố (do con trỏ lên đầu heap __brkval không được cập nhật khi free()).

Chạy đoạn mã sau để xem những vấn đề này trong các phiên bản 0023, 0022, vv Trong Arduino 1,0 mã sẽ hiển thị không có rò rỉ bộ nhớ:

#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() { 
} 

Bên cạnh đó, thư viện MemoryFree bạn đang sử dụng có thể cung cấp sai kết quả vì nó không tính đến danh sách miễn phí. Hãy thử phiên bản cập nhật này của 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

Cảm ơn bạn! Hóa ra đó là hàm freeMemory báo cáo các giá trị xấu. Sử dụng phương pháp cung cấp của bạn thay vào đó, cho kết quả chính xác và không có rò rỉ dường như xảy ra. –

+0

Tốt để biết các thư viện Arduino 1.0 là OK. Sẽ cập nhật câu trả lời. Cảm ơn! –

+0

Tôi đã cập nhật mã thư viện MemoryFree.cpp trên trang web Arduino (http://arduino.cc/playground/Code/AvailableMemory) phù hợp với câu trả lời được chấp nhận này. –

0

Nếu bạn xem qua Arduino source, bạn có thể gặp tệp ". \ Arduino-1.0 \ hardware \ arduino \ cores \ arduino \ WString.cpp". Trong tập tin này, tôi nhận thấy rằng String không có một constructor mặc định (parameterless). Có lẽ điều này có thể là vấn đề? Nghi ngờ, nhưng dù sao, nguồn sẽ giúp đỡ. May mắn nhất.

+0

Tôi đã xem xét tập tin đó, chủ yếu để xác minh rằng nó có một destructor. Tôi sẽ kiểm tra xem một mảng được khởi tạo với các giá trị có tạo ra sự khác biệt nào không. –

0

Nhận xét dòng String s[100]; và xem bạn có nhận được kết quả khác không. Dường như việc cấp phát bộ nhớ bạn thấy là do các hoạt động chuỗi trong hàm setup() của bạn, không phải là việc khai báo một chuỗi chuỗi cục bộ trong AllocateStrArr(). Bạn có thể xem WString.cppWString.h để thấy rằng operator+ đã bị ghi đè, do đó, mọi cuộc gọi đến String() hoặc nối bằng cách sử dụng + có thể tạo một đối tượng khác.

+0

Nhận xét rằng dòng đó mang lại sự khác biệt 0. –

Các vấn đề liên quan