C++ 指针指向自身的Arduino结构泄漏内存
我有一个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指针获得 项目对象的生成每分钟在我的循环中进行一次。问题是我会时不时地失去内存
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
结构分配内存?您需要显示更多信息