C++ 指针指向自身的Arduino结构泄漏内存

C++ 指针指向自身的Arduino结构泄漏内存,c++,memory-leaks,struct,arduino,C++,Memory Leaks,Struct,Arduino,我有一个arduino程序,我想将数据存储在动态列表中。为此,我使用以下struct: struct Project { boolean status; String name; struct Project* nextProject; }; 现在,我根据外部数据生成动态数量的Project对象。我只有第一个Project对象作为变量,其余的可以通过nextProject指针获得 项目对象的生成每分钟在我的循环中进行一次。问题是我会时不时地失去内存

我有一个arduino程序,我想将数据存储在动态列表中。为此,我使用以下
struct

struct Project {
  boolean         status;
  String          name;
  struct Project* nextProject;
};
现在,我根据外部数据生成动态数量的
Project
对象。我只有第一个
Project
对象作为变量,其余的可以通过
nextProject
指针获得

项目
对象的生成每分钟在我的
循环
中进行一次。问题是我会时不时地失去内存,直到它变空。
这就是我的主循环的样子:

void loop() {
  webServer(server);
  webClient();

  if (parseTimer(60)) {
    sendRequest();
  }
}
parseTimer
是一个非阻塞延迟函数,每60秒返回
true
sendRequest
生成
项目
对象)

我的记忆测量方法:

uint8_t* stackptr;
uint8_t* heapptr;

long getFreeMemory() {
  stackptr = (uint8_t *) malloc(4);
  heapptr  = stackptr;
  free(stackptr);
  stackptr = (uint8_t *) (SP);

  return long(stackptr) - long(heapptr);
}
这是每个循环的内存量:

1:  4716 *
2:  4716 *
3:  4716 *
4:  4671
5:  4687
6:  4587 *
7:  4736
8:  4587 *
9:  4559
10: 4577
11: 4515
12: 4527
13: 4587 *
14: 4479
15: 4497
16: 4435
17: 4447
18: 4587 *
19: 4399
20: 4417
21: 4355
22: 4367
23: 4587 *
24: 4319
内存越来越少,但在前几个循环之后,每第五个循环我就有
4587字节的可用内存。在大约280次循环后,程序内存不足,但在此之前,每5次循环正好有4587字节的可用内存。
有谁能解释一下这种奇怪行为的原因是什么,以及我如何创建一个更好的动态列表而不泄漏内存

更新

在每个循环中,生成、使用和删除
项目
对象。它是这样做的:

void sendRequest() {
  // at first it gets some remote data from a server the result is:
  String  names[]  = {"Project 1", "Project 2", "Project 3"};
  boolean states[] = {true, false, true};

  for(int i = 0; i <= projectCount; i++) {
    addProject(names[i], states[i]);
  }
}

// all variables that are not declarated here are declarated in the
// header file of the class
void addProject(String name, boolean state) {
  if (!startProject) {
    startProject = true;

    firstProject.status      = state;
    firstProject.name        = name;
    firstProject.nextProject = NULL;

    ptrToLastProject = &firstProject;
  } else {
    ptrToLastProject->nextProject = new Project();

    ptrToLastProject->nextProject->status      = tempProjectStatus;
    ptrToLastProject->nextProject->name        = tempData;
    ptrToLastProject->nextProject->nextProject = NULL;

    ptrToLastProject = ptrToLastProject->nextProject;
  }
}

void RssParser::resetParser() { 
  delete ptrToLastProject;
  [...]
}
void sendRequest(){
//首先,它从服务器获取一些远程数据,结果是:
字符串名称[]={“项目1”、“项目2”、“项目3”};
布尔状态[]={true,false,true};
for(int i=0;i nextProject=new Project();
ptrToLastProject->nextProject->status=tempProjectStatus;
ptrToLastProject->nextProject->name=tempData;
ptrToLastProject->nextProject->nextProject=NULL;
ptrToLastProject=ptrToLastProject->nextProject;
}
}
void RssParser::resetParser(){
删除ptrToLastProject;
[...]
}

首先,您没有泄漏内存,因为在每5次迭代中,您的内存都会回到4587字节

然而,这里出现了一个有趣的模式。您会注意到,在拥有4587字节之前对
getFreeMemory
进行的每一组调用总是80字节小于上一组

我猜在每个
sendRequest
上都会收到越来越多的数据,作为回报,您试图在循环中分配更多的内存。在某个地方释放它是很好的,但在某个时候您试图分配太多了

一种可能性是,您正在追加请求数据,而不是覆盖它,随后
projectCount
会不断增加

作为旁注,请注意这一点:

for(int i = 0; i <= projectCount; i++) {
    addProject(names[i], states[i]);
}

for(int i=0;i首先,您没有泄漏内存,因为在每5次迭代中,您的内存都会回到4587字节

然而,这里出现了一个有趣的模式。您会注意到,在拥有4587字节之前对
getFreeMemory
进行的每一组调用总是80字节小于上一组

我猜在每个
sendRequest
上都会收到越来越多的数据,作为回报,您试图在循环中分配更多的内存。在某个地方释放它是很好的,但在某个时候您试图分配太多了

一种可能性是,您正在追加请求数据,而不是覆盖它,随后
projectCount
会不断增加

作为旁注,请注意这一点:

for(int i = 0; i <= projectCount; i++) {
    addProject(names[i], states[i]);
}

for(inti=0;i在对项目的几乎每个功能进行大量研究和编写单元测试之后,我发现了错误

在我的
resetParser()
函数中,我只执行了一个
delete ptrToLastProject
。但是还有一个指向此对象的指针,因此内存没有释放。将此指针添加到
resetParser()
函数中修复了泄漏

delete firstProject.nextProject;

这是因为
firstProject
在堆栈上,有一个指向堆上列表中其他项目的指针。当我删除这个指针时,列表中的所有其他对象也会被它们的析构函数删除。

经过大量研究,并为我能够找到的项目的几乎每个功能编写了单元测试这个错误

在我的
resetParser()
函数中,我只执行了一个
delete ptrToLastProject
。但是还有一个指向此对象的指针,因此内存没有释放。将此指针添加到
resetParser()
函数中修复了泄漏

delete firstProject.nextProject;

这是因为
firstProject
在堆栈上,有一个指向堆上列表中其他项目的指针。当我删除此指针时,列表中的所有其他对象也会被它们的析构函数删除。

是否在每次循环迭代中创建新的项目对象?如果是这样,内存使用量增加是正常的容易,但这并不意味着您正在泄漏内存。您在哪里为
项目
结构分配内存?您需要显示更多代码,绝对没有任何迹象表明链表本身就是问题所在(声明很好).我对arduino开发一无所知。你为什么不使用
std::list
?添加了一些代码来显示我如何生成“list”@Dave sry,但我不能使用std函数。您是否在每次循环迭代中创建新的项目对象?如果是,内存使用量增加是正常的,并不意味着您正在泄漏内存。您在哪里为
Project
结构分配内存?您需要显示更多信息