![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с массивом строк. [D7, XP]
account1024 © (2007-12-11 17:07:00)Проблема начинается когда я освобождаю память (выдает ошибку - InvalidPointer).
TStrArrayType = ShortString;
TStrArray = array [0..255] of TStrArrayType;
PStrArray = ^TStrArray;
function MakeStrArray( sStr: string; sChar: string ): integer;
var
i1, i2: integer;
s: string;
begin
Result:= 0;
if bStrArrayLock then exit;
i2:= NumToken( sStr, sChar );
iStrArraySize:= i2;
GetMem( aStrArray, iStrArraySize * sizeof(TStrArrayType));
Result:= i2;
for i1:= 1 to i2 do
begin
s:= GetToken( sStr, sChar, i2 ); // GetToken - возвращает слово из строки (sStr) по номеру (i2) используя разделитель (sChar)
aStrArray^[i2]:= s;
end;
bStrArrayLock:= true;
end;
function GetStrArray( iIndx: integer ): TStrArrayType;
begin
if iStrArraySize < 1 then Result:= ''
else Result:= aStrArray^[iIndx];
end;
procedure FlushStrArray;
begin
FreeMem( aStrArray, iStrArraySize * sizeof(TStrArrayType) );
bStrArrayLock:= false;
end;
Что я делаю не так?
account1024 (2007-12-11 17:26:00) [1]Я дурак! Про [0..255] это я не углядел. Спасибо, все работает.
Сергей М. (2007-12-11 17:21:00) [2]
> FreeMem( aStrArray, iStrArraySize * sizeof(TStrArrayType)
> );
А если просто
FreeMem(aStrArray)
то та же ошибка ?
Григорьев Антон (2007-12-11 17:21:00) [3]Вот интересно... Массив вы объявили с диапазоном [0..255], а индекс у вас везде начинается с 1. Если вы для такого массива выделяете память на iStrArraySize, то индексы элементов будут лежать в диапазоне от 0 до iStrArraySize-1, а не от 1 до iStrArraySize, как в вашем коде. Когда вы обращаетесь к элементу с индексом iStrArraySize, вы на самом деле залезаете в память, уже не принадлежащую выделенному блоку, и тем самым портите в т.ч. и служебную информацию менеджера памяти о следующем блоке. Скорее всего, это и вызывает ошибку - при освобождении памяти менеджер памяти смотрит, какой блок идёт после вашего и пытается объединить два свободных блока в один, а так как информация уже испорчена, это у него не получается.
А ещё, при вызове FreeMem не надо указывать размер освобождаемой памяти - этот параметр оставлен только для совместимости c TP и в Delphi просто игнорируется - менеджер памяти сам знает, сколько освобождать.
Ну а самое правильное в такой ситуации - использовать динамический массив.
Palladin (2007-12-11 17:18:00) [4]не видно где объявлен aStrArray и тот ли aStrArray освобождается... самое интересное массив у тебя объявлен как [0.. а заполняешь ты егос 1 элемента, идет заброд за границы взятой памяти
account1024 (2007-12-11 17:13:00) [5]Забыл добавить в первый пост:
aStrArray: PStrArray;
iStrArraySize: integer;
bStrArrayLock: boolean = false;
account1024 (2007-12-11 17:11:00) [6][b]to Kolian[/b]
А почему так оно не работает?
Kolan (2007-12-11 17:08:00) [7]> Что я делаю не так?
Вы используете массив строк.
Используйте, TStrings (TStringList). Не забудьте начать с чтения справки.