在范围退出时未释放字符串数组

时间:2012-01-15 22:41:19

标签: c arduino

我在我的应用程序中遇到了一些严重的内存泄漏,所以我设置了这个非常简单的解决方案来测试String数组超出范围时会发生什么......

我知道String的旧TextString实现缺少析构函数,但是这个当前的实现似乎有它。

我正在使用this MemoryFree library请注意,此链接代码现已根据此问题的接受答案修复)。

该代码检查了两种情况:在两个不同的函数中分配char数组和字符串数组,以强制范围退出。

#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数组分配?

3 个答案:

答案 0 :(得分:4)

在测试String类(see forum post here)时,我在1.0之前的Arduino版本中遇到了内存处理问题。

String构造函数在内部使用realloc,这是导致问题的(avr libc)动态内存处理(由于指向堆顶部__brkval的指针未在{{{{}}上更新1}})。

运行以下代码以查看版本0023,0022等中的这些问题。在Arduino 1.0中,代码应显示无内存泄漏:

free()

此外,您使用的MemoryFree库可能会给出错误的结果,因为它没有考虑空闲列表。试试此#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.cpp

答案 1 :(得分:0)

如果查看Arduino source,可能会遇到“。\ arduino-1.0 \ hardware \ arduino \ cores \ arduino \ WString.cpp”文件。在这个文件中,我注意到String没有默认(无参数)构造函数。也许这可能是问题?令人怀疑,但无论如何,来源应该有所帮助。祝你好运。

答案 2 :(得分:0)

注释掉String s[100];行,看看你是否得到了不同的结果。您看到的内存分配看起来是由setup()函数中的字符串操作引起的,而不是AllocateStrArr()中的本地字符串数组的声明。您可以查看WString.cppWString.h以查看已覆盖operator+,因此每次调用String()或使用+进行连接都可能会创建另一个对象