![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите пожалуйста найти ошибку в коде
Денис11998833 © (2016-08-08 18:04:00)Есть код для хранения структур в массиве:
unit uTst;
interface
type
TGroupDests=(gdFile, gdReg, gdTweak, gdUnknown);
TScanGroupsItem=record
IdGroup: integer;
IdParentGroup: integer;
GroupDest: TGroupDests;
GroupName: pstring;
GroupDescr: pstring;
IconInd: integer;
VclFakeGroup: boolean;
SchedForFix: boolean;
end;
PScanGroupsItem=^TScanGroupsItem;
TScanGroupsList=array of PScanGroupsItem;
procedure TstLoader;
procedure TstUnloader;
var
ScanGroupsList: TScanGroupsList;
ScanGroupsCnt: integer;
TstText1, TstText2: string;
implementation
procedure TstLoader;
var
ScanGroupsItem: PScanGroupsItem;
i: integer;
begin
TstText1:='Tst text1';
TstText2:='Tst text2';
ScanGroupsCnt:=0;
for i := 0 to 40 do
begin
GetMem(ScanGroupsItem, SizeOf(TScanGroupsItem));
ScanGroupsItem^.IdGroup:=11;
ScanGroupsItem^.IdParentGroup:=111;
ScanGroupsItem^.GroupDest:=gdReg;
ScanGroupsItem^.GroupName:=@TstText1;
ScanGroupsItem^.GroupDescr:=@TstText2;
ScanGroupsItem^.VclFakeGroup:=False;
ScanGroupsItem^.SchedForFix:=True;
Inc(ScanGroupsCnt);
SetLength(ScanGroupsList, ScanGroupsCnt);
ScanGroupsList[ScanGroupsCnt]:=ScanGroupsItem;
end;
end;
procedure TstUnloader;
var i: integer;
begin
for i := 1 to ScanGroupsCnt do
FreeMem(PScanGroupsItem(ScanGroupsList[i]));
end;
end.
Вызываю TstLoader в OnCreate формы. При закрытии приложения, получаю access violationб в функции SysFreeMem, модуля GETMEM.INC:
function SysFreeMem(P: Pointer): Integer;
asm
{$ifdef CPU386}
{---------------32-bit BASM SysFreeMem---------------}
{On entry:
eax = P}
{Get the block header in edx}
mov edx, [eax - 4]
{Is it a small block in use?}
test dl, IsFreeBlockFlag + IsMediumBlockFlag + IsLargeBlockFlag
{Save the pointer in ecx}
mov ecx, eax
{Save ebx}
push ebx
{Get the IsMultiThread variable in bl}
mov bl, IsMultiThread
{Is it a small block that is in use?}
jnz @NotSmallBlockInUse
{Do we need to lock the block type?}
test bl, bl
{Get the small block type in ebx}
mov ebx, TSmallBlockPoolHeader[edx].BlockType
{Do we need to lock the block type?}
jnz @LockBlockTypeLoop
@GotLockOnSmallBlockType:
{Current state: edx = @SmallBlockPoolHeader, ecx = P, ebx = @SmallBlockType}
{Decrement the number of blocks in use}
sub TSmallBlockPoolHeader[edx].BlocksInUse, 1
{Get the old first free block}
mov eax, TSmallBlockPoolHeader[edx].FirstFreeBlock
{Is the pool now empty?}
jz @PoolIsNowEmpty
{Was the pool full?}
test eax, eax
{Store this as the new first free block}
mov TSmallBlockPoolHeader[edx].FirstFreeBlock, ecx
{Store the previous first free block as the block header}
lea eax, [eax + IsFreeBlockFlag]
mov [ecx - 4], eax
{Insert the pool back into the linked list if it was full}
jz @SmallPoolWasFull
{All ok}
xor eax, eax
{Unlock the block type}
mov TSmallBlockType[ebx].BlockTypeLocked, al
{Restore registers}
pop ebx
{Done}
ret
{Align branch target}
nop
Исключение в этой строчке:
{Unlock the block type}
mov TSmallBlockType[ebx].BlockTypeLocked, al
Подскажите пожалуйста, что не так делаю?..
Германн (2016-08-12 02:11:00) [1]
> Kilkennycat © (12.08.16 01:46) [8]
>
>
> > А в боевой сборке можно и
>
> спользовать LOW() HIGH()
Вот это полезный совет для любой сборки!
Kilkennycat (2016-08-12 01:46:00) [2]
> А в боевой сборке можно и
спользовать LOW() HIGH() или аналогичное
Тимохов Дима (2016-08-12 01:28:00) [3]
> Денис11998833 (08.08.16 18:04)
Коллега, а зачем ты отключил Range checking?
Поставил бы {R+} в коде или соотв. галку в настройках проекта - и сразу бы сам нашел.
Знаю, что многие отключают проверки на границы массива. Но мое имхо, что на стадии разработки это чертовски полезная штука.
А в боевой сборке можно и отключать.
Kilkennycat (2016-08-09 11:10:00) [4]там другое дело, там она с 1 начинается.
iop (2016-08-09 10:29:00) [5]што, и даже в цикле на фримем по длинне масива?
Kilkennycat (2016-08-09 10:15:00) [6]
> iop © (09.08.16 08:52) [3]
она для информативности. и надежности. просто "и" ненадежно и неинформативно
iop (2016-08-09 08:52:00) [7]ScanGroupsCnt - лишняя переменная
Денис11998833 (2016-08-08 19:33:00) [8]Спасибо большое! Вылетело из головы((
Игорь Шевченко (2016-08-08 19:03:00) [9]
> FreeMem(PScanGroupsItem(ScanGroupsList[i]));
FreeMem(PScanGroupsItem(ScanGroupsList[Pred(i)]));
Динамические массивы с нуля индексируются.