Форум: "Основная";
Текущий архив: 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.038 c