2 sam1029384756 sam1029384756 于 2014.01.10 23:35 提问

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 set,set2;//结点集合类对象
long x=10,y=45,g=3,h=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(x,y);
      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(x,y);
      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("(x,y,F,G,H)"));
    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(edge,n*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
(x,y,F,G,H)(10,45,3,3,0)
Free Ram: 1667
(x,y,F,G,H)(35,38,172,105,67)
Free Ram: 1599
(x,y,F,G,H)(3,108,522,315,207)
Free Ram: 1509
(x,y,F,G,H)(105,420,65730,33075,32655)
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:
(x,y,F,G,H)(10,45,3,3,0)
(x,y,F,G,H)(35,38,172,105,67)
(x,y,F,G,H)(3,108,522,315,207)
(x,y,F,G,H)(105,420,65730,33075,32655)
Set:
(x,y,F,G,H)(10,45,3,3,0)
(x,y,F,G,H)(35,38,172,105,67)
(x,y,F,G,H)(3,108,522,315,207)
(x,y,F,G,H)(105,420,65730,33075,32655)
Length de set:0
Set:
(x,y,F,G,H)(33390,66780,0,0,0)
(x,y,F,G,H)(0,33390,115621,33390,16695)
Free Ram: 901
Loop
Hello brave world!
i=0 j=1
Free Ram: 901
False
Hello brave world!
He

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!