一个车辆无线管理系统的上位机程序,总是运行一段时间就不停的弹出警告窗口,弹出一定数量后程序自动退出。
程序在运行过程中接收串口的数据,进行处理,然后在不同的监控界面显示,同时写入数据库,现在我怀疑是写数据库出的问题,
下面把部分代码贴出来,大家帮看看是哪个地方的毛病。
写数据库
procedure TfrmGarageManageMain.IsEventOccur;  //处理数据,判断是否车在车库,是否有人进入,是否有火警
var
   i:integer;
   strSQL:string;
   strCarNo:string;
begin   //判断车辆进出情况
   for i:=1 to iGarageCount do begin
      if (CarTime='全天') or ((CarTime='检查时间') and ((formatdatetime('hh:mm',time)>=CarTime1) and (formatdatetime('hh:mm',time)<=CarTime2)) or ((CarTime='停止时间') and ((formatdatetime('hh:mm',time)<=CarTime1) or (formatdatetime('hh:mm',time)>=CarTime2)))) then begin
         //打开插入数据的Query
         strSQL:='select top 1 * from hwjy_CarInout where PLACE='''+GaragePlace+'''';
         with Q do begin
            Close;
            SQL.Clear;
            SQL.Add(strSQL);
            Open;
         end;
         //查询车牌号
         strSQL:='select * from HWJY_GARAGE where GARAGE_NO='+inttostr(i)+' and POSITION_NO=1'
                  +' and PLACE='''+GaragePlace+'''';
         with QQ do begin
            Close;
            SQL.Clear;
            SQL.Add(strSQL);
            Open;
         end;
         if QQ.RecordCount=0 then begin
            strCarNo:='无牌照';
         end else begin
            strCarNo:=trim(QQ.Fieldbyname('CAR_NO').AsString);
         end;
         //1#车位有车进入
         if (Car1LBResultOld[i]=0) and (Car1LBResult[i]=1) then begin
            //写入数据库
                 MemoSerial.Lines.Add('第'+inttostr(i)+'车库1#车入库');
                 MemoSerial.lines.add('***********');
             with Q do begin
                Append;
                FieldByName('CAR_NO').AsString:=strCarNo;
                FieldByName('GARAGE_NO').AsString:=inttostr(i);
                FieldByName('POSITION_NO').AsString:='1';
                FieldByName('IOTIME').AsDateTime:=now;
                FieldByName('IOTYPE').AsString:='入库';
                FieldByName('PLACE').AsString:=GaragePlace;
                Post;
             end;
         end;
         //1#车位有车离开
         if (Car1LBResultOld[i]=1) and (Car1LBResult[i]=0) then begin
                 MemoSerial.Lines.Add('第'+inttostr(i)+'车库1#车出库');
                 MemoSerial.lines.add('******1*****');
             //写入数据库
             with Q do begin
                Append;
                FieldByName('CAR_NO').AsString:=strCarNo;
                FieldByName('GARAGE_NO').AsString:=inttostr(i);
                FieldByName('POSITION_NO').AsString:='1';
                FieldByName('IOTIME').AsDateTime:=now;
                FieldByName('IOTYPE').AsString:='出库';
                FieldByName('PLACE').AsString:=GaragePlace;
                Post;
             end;
         end;
         //查询车牌号
         strSQL:='select * from HWJY_GARAGE where GARAGE_NO='+inttostr(i)+' and POSITION_NO=2'
                  +' and PLACE='''+GaragePlace+'''';
         with QQ do begin
            Close;
            SQL.Clear;
            SQL.Add(strSQL);
            Open;
         end;
         if QQ.RecordCount=0 then begin
            strCarNo:='无牌照';
         end else begin
            strCarNo:=trim(QQ.Fieldbyname('CAR_NO').AsString);
         end;
         //2#车位有车进入
         if (Car2LBResultOld[i]=0) and (Car2LBResult[i]=1) then begin
                 MemoSerial.Lines.Add('第'+inttostr(i)+'车库2#车入库');
                 MemoSerial.lines.add('***********');
             //写入数据库
             with Q do begin
                Append;
                FieldByName('CAR_NO').AsString:=strCarNo;
                FieldByName('GARAGE_NO').AsString:=inttostr(i);
                FieldByName('POSITION_NO').AsString:='2';
                FieldByName('IOTIME').AsDateTime:=now;
                FieldByName('IOTYPE').AsString:='入库';
                FieldByName('PLACE').AsString:=GaragePlace;
                Post;
             end;
         end;
         //2#车位有车离开
         if (Car2LBResultOld[i]=1) and (Car2LBResult[i]=0) then begin
                 MemoSerial.Lines.Add('第'+inttostr(i)+'车库2#车出库');
                 MemoSerial.lines.add('***********');
            //写入数据库
             with Q do begin
                Append;
                FieldByName('CAR_NO').AsString:=strCarNo;
                FieldByName('GARAGE_NO').AsString:=inttostr(i);
                FieldByName('POSITION_NO').AsString:='2';
                FieldByName('IOTIME').AsDateTime:=now;
                FieldByName('IOTYPE').AsString:='出库';
                FieldByName('PLACE').AsString:=GaragePlace;
                Post;
             end;
         end;
      end;
   end;
end;
以下是弹出过的警告窗口信息
1.Access violation at address 07F43007 in module 'BORdbk70.dll',Read of address 08E50000.
2.Timed out waitting for process to terminate
3.Debugger fatal error during process reset:'Debug process is already running'.Please save your work and restar Delphi.
 上面的是在DELPHI下运行程序出现的
4.Access violation at address 00402F4F in module 'Pgaragemanage.exe'Read of address FFFFF9FF
 上面的是直接运行程序出现的,隔半秒不停的弹出,最后程序退出
查了一些资料,大部分说是内存泄漏问题,请问怎么解决呢?上火啊

解决方案 »

  1.   

    写数据库另一部分
    ////////////////////////////////////////////////////////////////////////////////
    procedure TfrmGarageManageMain.IsEventOccurMan;  //处理数据,是否有人进入
    var
       i:integer;
       h,m,s,mi:word;
       strSQL:string;
    begin
       
          //判断人进入情况
          if (ManTime='全天') or ((ManTime='检查时间') and ((formatdatetime('hh:mm',time)>=ManTime1) and (formatdatetime('hh:mm',time)<=ManTime2))  or ((ManTime='停止时间') and ((formatdatetime('hh:mm',time)<=ManTime1) or (formatdatetime('hh:mm',time)>=ManTime2)))) then begin
                 //提取数据库,判断是否有记录,并且已经超过了检查间隔时间
                 decodetime(now-manLastTime,h,m,s,mi);
                 if (h*3600+m*60+s>=manInterval) then begin
                   for i:=1 to iGarageCount do begin
                      if ManLBResult[i]=1 then begin
                      //写入数据库
                      strSQL:='select top 1 * from hwjy_ManInout where PLACE='''+GaragePlace+'''';
                      with Q do begin
                         Close;
                         SQL.Clear;
                         SQL.Add(strSQL);
                         Open;
                      end;
                      with Q do begin
                         Append;
                         FieldByName('GARAGE_NO').AsString:=inttostr(i);
                         FieldByName('INTIME').AsDateTime:=now;
                         FieldByName('PLACE').AsString:=GaragePlace;
                         Post;
                      end;
                      ManLastTime:=now;
                      //声音报警
                      PlayWav(Pchar(nWavPath),Pchar('37.wav'),false);
                   end;
             end;
          end;//判断有人进入情况
        end;
    end;////////////////////////////////////////////////////////////////////////////////
    procedure TfrmGarageManageMain.IsEventOccurFire;  //处理数据,是否有火警
    var
       i:integer;
       strSQL:string;
       h,m,s,mi:word;
    begin
         //是否启动判断火灾情况
        if (FireTime='全天') or ((FireTime='检查时间') and ((formatdatetime('hh:mm',time)>=FireTime1) and (formatdatetime('hh:mm',time)<=FireTime2)) or ((FireTime='停止时间') and ((formatdatetime('hh:mm',time)<=FireTime1) or (formatdatetime('hh:mm',time)>=FireTime2)))) then begin
            for i:=1 to iGarageCount do begin
             //发生火灾
            if fire[i]>=35 then begin
                   //声音报警
                 PlayWav(Pchar(nWavPath),Pchar('fire.WAV'),false);
             end;
             end;
            //提取数据库,判断是否有记录,并且已经超过了检查间隔时间
           decodetime(now-FireLastTime,h,m,s,mi);
           if (h*3600+m*60+s>=FireInterval*1) then begin
              FireLastTime:=now;
              for i:=1 to iGarageCount do begin
                  //写入数据库
                    strSQL:='select top 1 * from hwjy_fire where PLACE='''+GaragePlace+'''';
                    with Q do begin
                       Close;
                       SQL.Clear;
                       SQL.Add(strSQL);
                       Open;
                    end;
                    with Q do begin
                       Append;
                       FieldByName('GARAGE_NO').AsString:=inttostr(i);
                       FieldByName('FIRETIME').AsDateTime:=now;
                       FieldByName('PLACE').AsString:=GaragePlace;
                        if (fireFlag[i]=1) then begin
                         FieldByName('temperature').AsString:='-'+inttostr(fire[i]);
                       end else begin
                         FieldByName('temperature').AsString:=inttostr(fire[i]);
                       end;
                       if fire[i]>=35 then begin
                         FieldByName('type').AsString:='异常';
                       end else begin
                         FieldByName('type').AsString:='未见异常';
                       end;
                       Post;
                    end;
                 end;
             end;
          end; //判断火灾情况
    end;
      

  2.   

    定时器部分
    procedure TfrmGarageManageMain.TimerWriteDataTimer(Sender: TObject);
    begin
       ComputeLoop;
       if GarageTurnCount>1 then begin
          comm1.WriteCommData(pAnsiChar(commWriteData[intTurn]),length(commWriteData[intTurn]));
          sleep(20);
          MemoSerial.Lines.Add('车库在第 '+pAnsiChar(inttostr(intTurn)+' 排'));
          MemoSerial.lines.add('');
          intTurn:=intTurn+1;
          if intTurn>GarageTurnCount then intTurn:=1;
       end;
    end;串口接收数据并处理
    procedure TfrmGarageManageMain.Comm1ReceiveData(Sender: TObject;
      Buffer: Pointer; BufferLength: Word);
    var
       i,iGarageNum,iGarageNum1,iGarageNum2,iGarageNum3,b6,b5,b4,b3,b2,b1,b0,WD,RES1:integer;
       bytTemp:byte;
       tempTime,strSQL:string;
    begin
        try
           Receivestring:='';
           Move(Buffer^,pchar(@ReceiveData)^,BufferLength);//接收数据
          for i:=1 to BufferLength do
          begin
              Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';
          end;
            MemoSerial.Lines.Add(Receivestring);
            MemoSerial.lines.add('');
           if (RightStr(inttohex(ReceiveData[1]+ReceiveData[4],1),2))<>inttohex(ReceiveData[5],1) then begin
              tempTime:='有错误发生'+DateTimeToStr(now);
              MemoSerial.Lines.Add(tempTime);
              MemoSerial.lines.add('');
              exit;
            end;
            iGarageNum:=ReceiveData[1]-20;
            car1[iGarageNum]:=(ReceiveData[2] and $80) div $80;
            car2[iGarageNum]:=(ReceiveData[2] and $40) div $40;
            man[iGarageNum]:=(ReceiveData[2] and $08) div $08;
            
            //此处零下温度判断,1为零下,0为零上
            IF (((ReceiveData[3] and $F8) div $F8)=1) then begin
              fireFlag[iGarageNum]:=1;          b6:=(ReceiveData[3] and $04) div $04;
              if b6=1
              then b6:=0
              else b6:=1;
              b5:=(ReceiveData[3] and $02) div $02;
              if b5=1
              then b5:=0
              else b5:=1;
              b4:=(ReceiveData[3] and $01) div $01;
              if b4=1
              then b4:=0
              else b4:=1;
              b3:=(ReceiveData[4] and $08) div $08;
              if b3=1
              then b3:=0
              else b3:=1;
              b2:=(ReceiveData[4] and $04) div $04;
              if b2=1
              then b2:=0
              else b2:=1;
              b1:=(ReceiveData[4] and $02) div $02;
              if b1=1
              then b1:=0
              else b1:=1;
              b0:=(ReceiveData[4] and $01) div $01;
              if b0=1
              then b0:=0
              else b0:=1;          RES1:=b6*64+b5*32+b4*16+b3*8+b2*4+b1*2+b0;
              WD:=RES1+1;          fire[iGarageNum]:=WD;
            end else begin
              fireFlag[iGarageNum]:=0;
              fire[iGarageNum]:=ReceiveData[3]*16+ReceiveData[4]*1;
            end;
            car1Power[iGarageNum]:=(ReceiveData[2] and $20) div $20;
            car2Power[iGarageNum]:=(ReceiveData[2] and $10) div $10;
            if car1Power[iGarageNum]=1 then begin
                   with QLog do begin
                      Append;
                      FieldByName('ERRORINFO').AsString:='第 '+inttostr(iGarageNum)+ ' 号车库中1#车辆发生掉电!';
                      FieldByName('TIME').AsDateTime:=now;
                      FieldByName('PLACE').AsString:=GaragePlace;
                      Post;
                  end;
            end;
            if car2Power[iGarageNum]=1 then begin
                   with QLog do begin
                      Append;
                      FieldByName('ERRORINFO').AsString:='第 '+inttostr(iGarageNum)+ ' 号车库中2#车辆发生掉电!';
                      FieldByName('TIME').AsDateTime:=now;
                      FieldByName('PLACE').AsString:=GaragePlace;
                      Post;
                  end;
            end;
             DealwithData; //调用不加滤波的串口处理函数
        except
           exit;
        end;
    end;
      

  3.   

    串口处理后的数据进行滤波
    procedure TfrmGarageManageMain.DealWithData;  //串口数据判断,取值为0或者1    0代表不存在事件,1代表存在事件
    var
       i:integer;
    begin
           //分别滤波,车辆开始滤波
         if LBCount<=LBTimes then begin
           for i:=loopStart to loopEnd do begin
              Car1Count[i]:=Car1Count[i]+car1[i];
              Car2Count[i]:=Car2Count[i]+car2[i];
           end;
         end else begin
             for i:=1 to iGarageCount do begin
             //保存上一次滤波结果
             Car1LBResultOld[i]:=Car1LBResult[i];
             Car2LBResultOld[i]:=Car2LBResult[i];
             //得出本次滤波结果
             if (Car1Count[i]/LBTimes)>LBJunZhi then begin
                Car1LBResult[i]:=1;
                Car1LBResultReal[i]:=1;
             end else begin
                Car1LBResult[i]:=0;
                Car1LBResultReal[i]:=0;
             end;
             if (Car2Count[i]/LBTimes)>LBJunZhi then begin
                Car2LBResult[i]:=1;
                Car2LBResultReal[i]:=1;
             end else begin
                Car2LBResult[i]:=0;
                Car2LBResultReal[i]:=0;
             end;
             Car1Count[i]:=0;
             Car2Count[i]:=0;
          end;
          LBCount:=0;
          IsEventOccur;
         end;
       //人数据情况
          for i:=1 to iGarageCount do begin
              //保存上一次结果
              ManLBResultOld[i] :=ManLBResult[i];
              //得出本次结果
              if man[i]=1 then begin
                 ManLBResult[i]:=1;
              end else begin
                 ManLBResult[i]:=0;
              end;
          end;
          IsEventOccurMan;
          //火灾数据情况
          IsEventOccurFire;end;
      

  4.   


    定时器部分
    procedure TfrmGarageManageMain.TimerWriteDataTimer(Sender: TObject);
    begin
    //----------------------------------------------------------------
    进入定时器后应该要执行Timer.Enabled := False;
       ComputeLoop;    if GarageTurnCount>1 then begin
          comm1.WriteCommData(pAnsiChar(commWriteData[intTurn]),length(commWriteData[intTurn]));
          sleep(20);
          MemoSerial.Lines.Add('车库在第 '+pAnsiChar(inttostr(intTurn)+' 排'));
          MemoSerial.lines.add('');
          intTurn:=intTurn+1;
          if intTurn>GarageTurnCount then intTurn:=1;
       end;
    //----------------------------------------------------------------
    退出时定时器后应该要执行Timer.Enabled := True;end;
      

  5.   

    procedure TfrmGarageManageMain.Comm1ReceiveData(Sender: TObject;
      Buffer: Pointer; BufferLength: Word);
    var
       i,iGarageNum,iGarageNum1,iGarageNum2,iGarageNum3,b6,b5,b4,b3,b2,b1,b0,WD,RES1:integer;
       bytTemp:byte;
       tempTime,strSQL:string;
    begin
        try
           Receivestring:='';
           Move(Buffer^,pchar(@ReceiveData)^,BufferLength);//接收数据
          for i:=1 to BufferLength do
          begin
              Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';
    最近查了一下程序,发现上面的语句有数组越界问题,就是这句:for i:=1 to BufferLength do,这个软件是接收无线模块送入串口的数据,有时空中产生误码或干扰一下传上来的字节超过了ReceiveData[i]的定义界限就出现问题,现在改成for i:=1 to 7 do,运行了两天,以为解决了呢,又出现类似问题,弄的我头大,因为是初学Delphi,程序的大框架已经是别人编完的了,实在是找不出问题所在,仍在观察!
      

  6.   

    问题解决了吗?看这个能行不
    var
       Buf:Array[0..1024]OF Char;
    Move(Buffer^,Buf,BufferLength);
    Receivestring:=String(Buf);
      

  7.   

    对了在这里
    for i:=1 to BufferLength do
          begin
              Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';改成
    for i:=0 to BufferLength-1 do   ////////....
          begin
              Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';