![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
выделение памяти с ошибкой [D7, Win2k, WinXP]
Arm79 © (2007-02-02 12:54:00)Имеются следующие описания типов:
PRow = ^TRow;
TRow = packed record
FldCount: Byte;
RowLen: Integer;
RowData: record end;
end;
PTable = ^TTable;
TTable = record
Ref: Integer;
RowCount: Integer;
TblData: TRow;
end;
Процедура:
procedure TList.LoadFromBuffer(Buffer: PChar; var Position: integer): boolean;
var
i : integer;
Table: PTable;
Row : PRow;
BA : TByteArray; // array of byte
begin
Table := PTable(Buffer); // первые 8 байт это поля Ref и RowCount
for i := 0 to Table.RowCount-1
do begin
GetMem(Row, SizeOf(TRow)); // почему то на этой строчке возникает Exception с сообщением access violation по такому то адресу. Причем каждый раз на 5 итерацию. RowCount > 250
Row^.FldCount := ReadByte(Buffer, Position); // читает 1 байт
Row^.RowLen := ReadInt4(Buffer, Position); // читает 4 байта
BA := ReadBytes(Buffer, Row^.RowLen, Position);
System.Move(BA[0], Row^.RowData, Length(BA));
Add(Row);
end;
end;
При каких условиях GetMem (как и AllocMem) может выдавать ошибку?
Сергей М. (2007-02-02 14:20:00) [1]
> У вас очень интересная реализация
Что же там интересного ? Тривиальная задача, тривиальный же код ..
Arm79 (2007-02-02 13:59:00) [2]Большое спасибо, не думал, что пойдете на трату своего времени для демонстрации )
Мне был важен принцип, дальше я сам сделал бы. У вас очень интересная реализация, приму на заметку.
Сергей М. (2007-02-02 13:55:00) [3]procedure ReadBytes(DataIn, DataOut: PChar; Count: integer; var Position: integer);
var
i:integer;
begin
for i := 0 to Count-1 do begin
DataOut[i] := ReadByte(DataIn, Position);
end;
procedure TList.LoadFromBuffer(Buffer: PChar; var Position: integer): boolean;
var
i : integer;
Table: PTable;
Row : PRow;
tmpFldCount, tmpRowLen: Integer;
begin
Table := PTable(Buffer);
for i := 0 to Table.RowCount-1 do begin
tmpFldCount := ReadByte(Buffer, Position); // читает 1 байт
tmpRowLen := ReadInt4(Buffer, Position); // читает 4 байта
GetMem(Row, SizeOf(TRow) + tmpRowLen);
Row.FldCount := tmpFldCount;
Row.RowLen := tmpRowLen;
ReadBytes(Buffer, @Row.RowData, Position);
Add(Row);
end;
end;
Arm79 (2007-02-02 13:34:00) [4]
> Anatoly Podgoretsky © (02.02.07 13:31) [12]
> > Arm79 (02.02.2007 13:25:08) [8]
>
> > то есть выделяю память равную 5, а потом к этой области
> памяти дописываю кусок
>
> Зачем ты так делаешь?
потому что руки кривые
поэтому и на форуме, уму разуму набираюсь
Anatoly Podgoretsky (2007-02-02 13:34:00) [5]> () []
> как выделить память под поле RowData?
Это не имеет смысла дела, поскольку данное поле нулевой длины.
Сергей М. (2007-02-02 13:32:00) [6]
> я лично вижу в памяти как
> BIIIIDDDDDD...DDDDD // byte, integer, data
>
Все правильно.
Своим "дописанным" DDDDDD...DDDDD ты изгадил содержимое некоего участка памяти, тебе не принадлежащего. И вполне возможно, что в этом участке лежат внутренние данные менеджера памяти, ты их беспардонно покоцал, поэтому менеджер и дает тебе отлуп в виде AV.
Anatoly Podgoretsky (2007-02-02 13:31:00) [7]> Arm79 (02.02.2007 13:25:08) [8]
> то есть выделяю память равную 5, а потом к этой области памяти дописываю кусок
Зачем ты так делаешь?
Arm79 (2007-02-02 13:30:00) [8]тогда просьба )
как выделить память под поле RowData?
Сергей М. (2007-02-02 13:28:00) [9]
> выделяю память равную 5, а потом к этой области памяти дописываю
> кусок
Куда дописываешь-то ? В память, которую ты не выделял ? Это же нонсенс)
Arm79 (2007-02-02 13:26:00) [10]
> Сергей М. © (02.02.07 13:22) [6]
>
> > TByteArray; // array of byte
>
>
> А зачем ты использовал идентификатор TByteArray ? Он уже
> определен в SysUtils как статический массив !
SysUtils в модулях идет раньше моего, поэтому TByteArray не является статическим и используется мое описане типа
Arm79 (2007-02-02 13:25:00) [11]правильно.
тип
TRow = packed record
FldCount: Byte;
RowLen: Integer;
RowData: record end;
end;
я лично вижу в памяти как
BIIIIDDDDDD...DDDDD // byte, integer, data
то есть выделяю память равную 5, а потом к этой области памяти дописываю кусок
System.Move(BA[0], Row^.RowData, Length(BA));
Сергей М. (2007-02-02 13:24:00) [12]+ см. palva © (02.02.07 13:22) [5]
Сергей М. (2007-02-02 13:22:00) [13]
> TByteArray; // array of byte
А зачем ты использовал идентификатор TByteArray ? Он уже определен в SysUtils как статическиймассив !
palva (2007-02-02 13:22:00) [14]> GetMem(Row, SizeOf(TRow));
Здесь SizeOf(TRow) равно 5. Т. е. вы не выделяете память под RowData ?
Arm79 (2007-02-02 13:17:00) [15]Это суперконструкция из API, поставляемого к dll, написанной на C, а не моя придумка
предполагается что в RowData будет непрерывный кусок данных, с разной длиной.
MBo (2007-02-02 13:13:00) [16]> RowData: record end;
Что это?
Arm79 (2007-02-02 13:09:00) [17]
function ReadBytes(Data: PChar; Count: integer; var Position: integer): TByteArray;
var
i:integer;
begin
SetLength(Result, Count);
for i := 0 to Count-1
do begin
Result[i] := ReadByte(Data, Position);
end;
end;
Сергей М. (2007-02-02 13:05:00) [18]А что, в теле ReadBytes() тоже GetMem() вызывается ?