Форум: "Начинающим";
Текущий архив: 2018.09.23;
Скачать: [xml.tar.bz2];
ВнизПомогите пожалуйста найти ошибку в коде Найти похожие ветки
← →
Денис11998833 (2016-08-08 18:04) [0]Есть код для хранения структур в массиве:
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-08 19:03) [1]
> FreeMem(PScanGroupsItem(ScanGroupsList[i]));
FreeMem(PScanGroupsItem(ScanGroupsList[Pred(i)]));
Динамические массивы с нуля индексируются.
← →
Денис11998833 (2016-08-08 19:33) [2]Спасибо большое! Вылетело из головы((
← →
iop © (2016-08-09 08:52) [3]ScanGroupsCnt - лишняя переменная
← →
Kilkennycat © (2016-08-09 10:15) [4]
> iop © (09.08.16 08:52) [3]
она для информативности. и надежности. просто "и" ненадежно и неинформативно
← →
iop © (2016-08-09 10:29) [5]што, и даже в цикле на фримем по длинне масива?
← →
Kilkennycat © (2016-08-09 11:10) [6]там другое дело, там она с 1 начинается.
← →
Тимохов Дима © (2016-08-12 01:28) [7]
> Денис11998833 (08.08.16 18:04)
Коллега, а зачем ты отключил Range checking?
Поставил бы {R+} в коде или соотв. галку в настройках проекта - и сразу бы сам нашел.
Знаю, что многие отключают проверки на границы массива. Но мое имхо, что на стадии разработки это чертовски полезная штука.
А в боевой сборке можно и отключать.
← →
Kilkennycat © (2016-08-12 01:46) [8]
> А в боевой сборке можно и
спользовать LOW() HIGH() или аналогичное
← →
Германн © (2016-08-12 02:11) [9]
> Kilkennycat © (12.08.16 01:46) [8]
>
>
> > А в боевой сборке можно и
>
> спользовать LOW() HIGH()
Вот это полезный совет для любой сборки!
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2018.09.23;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.006 c