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

Sil*_*sen 11 c arduino

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

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

我正在使用这个MemoryFree库(请注意,此链接代码现已根据此问题的已接受答案进行修复).

该代码检查了两种情况:在两个不同的函数中分配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 */ }
Run Code Online (Sandbox Code Playgroud)

输出:

CHAR*:1710之前,1710之后,Diff 0
STRING:1645之前,1309之后,Diff 336

为什么String不从内存中擦除数组分配?

Mat*_*och 4

在测试该类时,我在 1.0 之前的 Arduino 版本中遇到了内存处理问题String请参阅此处的论坛帖子)。

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

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

#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() {
}
Run Code Online (Sandbox Code Playgroud)

此外,您使用的 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;
}
Run Code Online (Sandbox Code Playgroud)