Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.07.25;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.047 c
1-1089701507
sergeii
2004-07-13 10:51
2004.07.25
Подскажите как в строке чисел наитйти букву


1-1089638173
Alkmas
2004-07-12 17:16
2004.07.25
Как узнать о состоянии процесса ?


1-1089543562
ltexcimer
2004-07-11 14:59
2004.07.25
максимальный размер переменной и запись в файл


1-1089701428
vlad_ri
2004-07-13 10:50
2004.07.25
Пойнтеры


14-1088935709
ИМХО
2004-07-04 14:08
2004.07.25
Что такое блог?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский