问题描述
- Arduino C编程中free()函数挂机
- 最近我在尝试写一个描述机器人比赛场地的代码时,在内存分配上遇到了挂机的问题。代码在Arduino提供的编译平台上全部通过,但是在实际运行时,往往无法跑完测试程序。经过测试发现代码在obstacle对象的构造函数中调用的segajouter(segment tmp)的free(void*ptr)函数中挂机。Arduino使用的是Uno
主题测试程序如下:
#include ""ensemble.h""
#include ""segment.h""
#include ""jonction.h""
#include ""obstacle.h""
ensemble setset2;//结点集合类对象
long x=10y=45g=3h=0;//设置参数
void setup()
{
Serial.begin(115200);
Serial.println(F(""Please input a digit:""));
}
void loop()
{
//=====================================================
//Teste de la classe obstacle障碍物类测试jonction test; if(Serial.available()>0) { Serial.print(F(""Free Ram: ""));//显示可用内存 Serial.println(freeRam());//显示可用内存 Serial.read(); Serial.print(set2.length()); for(int i=0;i<4;i++) { test.set_point(xy); test.set_g(g); test.set_h(h); x=y-x; y=g+x; g=x*g; h=g-y; set2.ajouter(test); Serial.print(F(""Free Ram: "")); Serial.println(freeRam()); output(set2.jonc()[i]);//输出读取内容(可能有出入) //因为添加结点时已经对集合中元素依据f()的大小 //排序 } Serial.print(F(""Free Ram:""));//显示可用内存 Serial.println(freeRam());//显示可用内存 obstacle obs(set2); Serial.print(F(""Free Ram:""));//显示可用内存 Serial.println(freeRam());//显示可用内存 Serial.print(F(""NumJonc:""));//输出结点数 Serial.println(obs.NumJonc()); Serial.print(F(""NumEdge:""));//输出边数 Serial.println(obs.NumEdge()); set=obs.jonc(); Serial.println(F(""Set2:"")); for(int i=0;i<set2.length();i++)//查看set2对象记录的结点 output(set2.jonc()[i]); Serial.println(F(""Set:""));//查看set对象记录的结点 for(int i=0;i<set.length();i++) output(set.jonc()[i]); set.vide();//清空set对象 Serial.print(F(""Length de set:""));//查看set对象元素个数 Serial.println(set.length()); x=h;//重新设置测试值 y=g; g=y-x; h=g/2; for(int i=0;i<2;i++) { test.set_point(xy); test.set_g(g); test.set_h(h); x=y-x; y=g+x; g=y%x; h=g*x; set.ajouter(test);//更新set集合 } Serial.println(F(""Set:""));//查看set元素 for(int i=0;i<set.length();i++) output(set.jonc()[i]); obstacle ob(set);//创建障碍物对象 if(ob==obs)//检测重载算符== Serial.println(F(""True"")); else { Serial.println(F(""False"")); ob.reset(set2);//重置ob,使得ob与obs相同 if(ob==obs)//检测重载算符== Serial.println(F(""True"")); else Serial.println(F(""Err"")); } }}//功能函数void output(jonction test1)//输出结点参数{ Serial.print(F(""(xyFGH)"")); Serial.print('('); Serial.print(test1.getx()); Serial.print(''); Serial.print(test1.gety()); Serial.print(''); Serial.print(test1.f()); Serial.print(''); Serial.print(test1.g()); Serial.print(''); Serial.print(test1.h()); Serial.println(')');}long input()//读取输入{ long n=0; boolean flag=false; char ch; if(Serial.available()>0) { ch=Serial.read(); if(ch=='-') { flag=true; delay(2); ch=Serial.read(); } n=long(ch-'0'); delay(2); } while(Serial.available()>0) { ch=Serial.read(); if((ch-'0')<10&&(ch-'0')>=0) n=10*n+long(ch-'0'); else break; delay(2); } if(flag) n*=-1; return n;}int freeRam ()//检测可用内存{extern int __heap_start *__brkval;int v;return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);}
类里头是这样定义的:
#include ""obstacle.h"" #include ""ensemble.h"" #include ""segment.h"" #include ""stdlib.h"" #include ""Arduino.h""int freeRam1 (){extern int __heap_start *__brkval;int v;return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);}void obstacle::segajouter(segment tmp)//Generer une liste de segment dynamiquement//n indique le nombre des éléments de *s{ segment *ss; n+=1; Serial.print(F(""Hello "")); ss=(segment*)malloc(sizeof(tmp)*n); if (ss == NULL) Serial.println(F(""malloc failed!"")); for(int i=0;i<n-1;i++) ss[i]=edge[i]; ss[n-1]=tmp;// s=(segment*)realloc(edgen*sizeof(tmp)); Serial.print(F(""brave ""));// if(s!=NULL)// edge=s;// edge[n-1]=tmp; free(edge); Serial.println(F(""world!"")); edge=ss; ss=NULL;}obstacle::obstacle(ensemble set){ vertex=set; Serial.print(F(""Free Ram: "")); Serial.println(freeRam1()); N=set.length(); n=0; Serial.println(F(""Loop"")); for(int i=0;i<N-1;i++) for(int j=i+1;j<N;j++) { segment tmp(vertex.jonc()[i]vertex.jonc()[j]); segajouter(tmp); Serial.print(F(""i="")); Serial.print(i); Serial.print(F("" j="")); Serial.println(j); Serial.print(F(""Free Ram: "")); Serial.println(freeRam1()); }}int obstacle::NumJonc(){ return N;}int obstacle::NumEdge(){ return n;}void obstacle::reset(ensemble set){ vertex=set; free(edge); N=set.length(); n=0; for(int i=0;i<N-1;i++) for(int j=i+1;j<N;j++) { segment tmp(vertex.jonc()[i]vertex.jonc()[j]); segajouter(tmp); }}ensemble obstacle::jonc(){ return vertex;}segment* obstacle::Edge(){ return edge;}boolean obstacle::operator ==(obstacle ob){ if(ob.jonc().length()==vertex.length()&&ob.jonc().jonc()==vertex.jonc()) return true; return false;}
以下是第一次在单片机上跑程序的反馈(由于原注释是部分使用法语的,可能与前面的程序的显示内容有点出入):
Veuillez entrer huit nombres en les s??parant par ' ':
Free Ram: 1737
0Free Ram: 1713
(xyFGH)(1045330)
Free Ram: 1667
(xyFGH)(353817210567)
Free Ram: 1599
(xyFGH)(3108522315207)
Free Ram: 1509
(xyFGH)(105420657303307532655)
Free Ram:1509
Free Ram: 1435
Loop
Hello brave world!
i=0 j=1
Free Ram: 1435
Hello brave world!
i=0 j=2
Free Ram: 1435
Hello brave world!
i=0 j=3
Free Ram: 1301
Hello brave world!
i=1 j=2
Free Ram: 1123
Hello brave world!
i=1 j=3
Free Ram: 901
Hello brave world!
i=2 j=3
Free Ram: 901
Free Ram:975
NumJonc:4
NumEdge:6
Set2:
(xyFGH)(1045330)
(xyFGH)(353817210567)
(xyFGH)(3108522315207)
(xyFGH)(105420657303307532655)
Set:
(xyFGH)(1045330)
(xyFGH)(353817210567)
(xyFGH)(3108522315207)
(xyFGH)(105420657303307532655)
Length de set:0
Set:
(xyFGH)(3339066780000)
(xyFGH)(0333901156213339016695)
Free Ram: 901
Loop
Hello brave world!
i=0 j=1
Free Ram: 901
False
Hello brave world!
He