Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.07.25;
Скачать: CL | DM;

Вниз

Мистика !!! Где утечка ???   Найти похожие ветки 

 
Andy BitOff ©   (2004-07-08 19:05) [0]

Или я тупой или одно из двух. Помогите, может, Вы профессиональным взглядом увидите сразу или Вы знаете, что-то, чего не знаю я. Подскажите. Вот код рожденный как продолжение ветки http://delphimaster.net/view/1-1089207932/


type
 TDirection = (Up, Down);

type
 TActionForPrint = (OpenFilePR, AllPrint, CurrentPrint, RangePrint);

type
 TRangeSeting = Record
   CurrentPage : integer;
   RangeStart : integer;
   RangeEnd : integer;
   Direction : TDirection;
 end;

type
 TPrintHistory = Record
   DataT : TDateTime;
   PrinterIndex : integer;
   OpenedFile : string;
   Action : TActionForPrint;
   RangeSeting : TRangeSeting;
 end;

var
 HistoryAr: array of TPrintHistory;

procedure TMainForm.PLSaveHistory;
const
 FName:PChar="PrintHistory.prh";
var
 i,i1,SizeItem,CurSize:integer;
 HighSize:boolean;
 hf:HFILE;
 MS:array of Byte;
 ///////////
 procedure CopyItem(f:PByteArray);
 var
   a:integer;
 begin
   SetLength(MS,SizeItem+CurSize+1);
   For a:=0 to SizeItem do begin
     if a=0 then begin
       MS[a+CurSize]:=SizeItem;
       inc(CurSize);
     end;
     MS[a+CurSize]:=f[a];
   end;
   inc(CurSize,SizeItem);
 end;
////////////
begin
 CurSize:=1;
 SetLength(MS,1);
 MS[0]:=Length(HistoryAr);
 Try
   for i:=0 to Length(HistoryAr)-1 do begin
     SizeItem:=SizeOf(HistoryAr[i].DataT);
     CopyItem(@HistoryAr[i].DataT);

     SizeItem:=SizeOf(HistoryAr[i].PrinterIndex);
     CopyItem(@HistoryAr[i].PrinterIndex);

     SizeItem:=Length(HistoryAr[i].OpenedFile);
     SetLength(MS,SizeItem+CurSize+1);
     HighSize:=False;
     if SizeItem>255 then begin   // если строка больше чем 255, то записываем 0 затем word - длина
       HighSize:=True;
       SetLength(MS,Length(MS)+2);
     end;
     For i1:=0 to SizeItem do begin
       if i1=0 then begin
         if HighSize then begin
           MS[i1+CurSize]:=0;
           inc(CurSize);
           MS[i1+CurSize]:=SizeItem;
           inc(CurSize);
           SizeItem:=SizeItem shr 8;
           MS[i1+CurSize]:=SizeItem;
           inc(CurSize);
         end
         else begin
           MS[i1+CurSize]:=SizeItem;
           inc(CurSize);
         end;
       end;
       MS[i1+CurSize]:=ORD(PChar(HistoryAr[i].OpenedFile)[i1]);
     end;
     inc(CurSize,SizeItem);

     SizeItem:=SizeOf(HistoryAr[i].Action);
     CopyItem(@HistoryAr[i].Action);

     SizeItem:=SizeOf(HistoryAr[i].RangeSeting.CurrentPage);
     CopyItem(@HistoryAr[i].RangeSeting.CurrentPage);

     SizeItem:=SizeOf(HistoryAr[i].RangeSeting.RangeStart);
     CopyItem(@HistoryAr[i].RangeSeting.RangeStart);

     SizeItem:=SizeOf(HistoryAr[i].RangeSeting.RangeEnd);
     CopyItem(@HistoryAr[i].RangeSeting.RangeEnd);

     SizeItem:=SizeOf(HistoryAr[i].RangeSeting.Direction);
     CopyItem(@HistoryAr[i].RangeSeting.Direction);
   end;
   hf:=_lCreat(FName,0);
   if hf<>HFILE_ERROR then begin
     if _lwrite(hf,PChar(MS), Length(MS)) =HFILE_ERROR then DeleteFile(FName);
     _lClose(hf);
   end;
   PLHistory.Clear;
 finally
   if MS<>nil then MS:=nil;
 end;
end;

Сам он работает нормально, т.е. делает, то что от него требуется, но вот дальше… В какой-то момент программа вываливается с сообщением о не возможности обратиться к такой-то ячейки памяти. Смысл абсолютно ясен. Не ясно ГДЕ утечка.

ЗЫ Предоставлю любую интересующую информацию :) (соответственно по теме :) )


 
Fay ©   (2004-07-08 19:18) [1]

Если не секрет, в какой строке?


 
Fay ©   (2004-07-08 19:23) [2]

Немного смущает 8)
For i1:=0 to SizeItem do begin


 
Andy BitOff ©   (2004-07-08 19:32) [3]


Если не секрет, в какой строке?


Вот в этом-то как раз и проблема. Процедура обрабатывается нормально, как и задумано. Но дальше по программе, в разных местах вываливается. Почему именно эта процедура? Потому, что если ее закоментировать, то никаких проблем!!! На самом деле скажу даже больше. Если поставить вместо SetLength(MS,1); -> SetLength(MS,1000);  и убрать все остальные SetLength"ы, то и тогда работает нормально, но этот вариант не подходить, т.к. размер данных неизвестен.

For i1:=0 to SizeItem do begin
Это потому, что первым байтом пишется сам SizeItem, а затем данные длиной SizeItem.


 
Fay ©   (2004-07-08 19:43) [4]

Отвлекаясь от темы, замечу, что код ужасный (IMHO). Вы знаете слова High и Low?


 
Семен Сорокин ©   (2004-07-08 19:55) [5]

if SizeItem>255 then begin   // если строка больше чем 255, то записываем 0 затем word - длина
      HighSize:=True;
      SetLength(MS,Length(MS)+2);
    end;
    For i1:=0 to SizeItem do begin
      if i1=0 then begin
        if HighSize then begin
          MS[i1+CurSize]:=0;
          inc(CurSize);
          MS[i1+CurSize]:=SizeItem;          
          inc(CurSize);
          SizeItem:=SizeItem shr 8;
          MS[i1+CurSize]:=SizeItem;
          inc(CurSize);
        end
        else begin
          MS[i1+CurSize]:=SizeItem;
          inc(CurSize);
        end;
      end;
      MS[i1+CurSize]:=ORD(PChar(HistoryAr[i].OpenedFile)[i1]);
    end;


значит SizeItem может быть > 255
а Вы пытаетесь записать в byte это значение, как Вы думаете что будет записано?


 
Andy BitOff ©   (2004-07-08 19:56) [6]

Ну вообщем-то да, это соответственно наибольший и наименьший индекс массива.


 
Семен Сорокин ©   (2004-07-08 19:58) [7]

все вижу, в двух записях :))


 
Andy BitOff ©   (2004-07-08 19:59) [8]


а Вы пытаетесь записать в byte это значение, как Вы думаете что будет записано?

Я проверял, будет записан младший байт DWord"а соответственно от 0 до 255.


 
Palladin ©   (2004-07-08 20:00) [9]

Ужасы какие

if i1=0 then begin
        if HighSize then begin
          MS[i1+CurSize]:=0;
          inc(CurSize);
          MS[i1+CurSize]:=SizeItem;
          inc(CurSize);
          SizeItem:=SizeItem shr 8;
          MS[i1+CurSize]:=SizeItem;
          inc(CurSize);
        end

если i1 итак 0 какого черта нужно его все время прибавлять?

MS[CurSize]:=0;
MS[CurSize+1]:=SizeItem;
MS[CurSuze+2]:=SizeItem SHR 8;
SizeItem:=SiteItem SHR 8;
Inc(CurSize,3);

не правда ли проще и понятней?
вообще говоря весь этот цикл - склеп полный путанных тайн... для подобных вещей существует while...

при поиске ошибок не надо ромашек: "заремарким, не заремарким"... нужно упрощать написанное... исполнять в уме, трассировать в плоть до создания текстового файла журнала выполнения процедуры...


 
Andy BitOff ©   (2004-07-08 20:07) [10]

Ну хорошо, застыдили, весь красный уже сижу. Я обычно занимаюсь оптимизацией когда, то что написано работает, а это не работает и если работать не будет то выкину и напишу по другому, хоть в ини-файл.
Но на самом деле уже страшное желание узнать в чем загвоздка, чтобы в будущем не нарваться на аналогичные проблемы.

ИМХО.ИМХО.ИМХО.ИМХО.


 
Семен Сорокин ©   (2004-07-08 20:12) [11]

это так задумано с обратным смещением заносить?

   For i1:=0 to SizeItem do begin
     ...
     MS[i1+CurSize]:=ORD(PChar(HistoryAr[i].OpenedFile)[i1]);
   end;


 
Palladin ©   (2004-07-08 20:14) [12]

Ошибка вот здесь
procedure CopyItem(f:PByteArray);
var
  a:integer;
begin
  SetLength(MS,SizeItem+CurSize+1);
  For a:=0 to SizeItem-1 do begin
    if a=0 then begin
      MS[a+CurSize]:=SizeItem;
      inc(CurSize);
    end;
    MS[a+CurSize]:=f[a];
  end;
  inc(CurSize,SizeItem);
end;


 
Palladin ©   (2004-07-08 20:18) [13]


> Семен Сорокин ©   (08.07.04 20:12)

и это тоже кстати говоря... :) упрощайте код люди... ну неужели нельзя было просто написать
MS[i1+CurSize]:=Byte(HistoryAr[i].OpenedFile[i1]) ?
сразу бы нашел ошибку...


 
Andy BitOff ©   (2004-07-08 20:24) [14]

Спасибо!



Страницы: 1 вся ветка

Текущий архив: 2004.07.25;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.038 c
1-1089636446
bobj
2004-07-12 16:47
2004.07.25
TDate и Windows


14-1087913563
cyborg
2004-06-22 18:12
2004.07.25
RoboWarz


14-1089021380
VEG
2004-07-05 13:56
2004.07.25
Подхватил какой-то троянец


11-1076575330
Аид
2004-02-12 11:42
2004.07.25
Помогите с наследованием КОЛ объектов


4-1086858192
Dmitriy_R
2004-06-10 13:03
2004.07.25
Управление чужой программой