Форум: "Начинающим";
Текущий архив: 2007.02.18;
Скачать: [xml.tar.bz2];
Внизвыделение памяти с ошибкой Найти похожие ветки
← →
Arm79 © (2007-02-02 12:54) [0]Имеются следующие описания типов:
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 13:05) [1]А что, в теле ReadBytes() тоже GetMem() вызывается ?
← →
Arm79 © (2007-02-02 13:09) [2]
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;
← →
MBo © (2007-02-02 13:13) [3]> RowData: record end;
Что это?
← →
Arm79 © (2007-02-02 13:17) [4]Это суперконструкция из API, поставляемого к dll, написанной на C, а не моя придумка
предполагается что в RowData будет непрерывный кусок данных, с разной длиной.
← →
palva © (2007-02-02 13:22) [5]> GetMem(Row, SizeOf(TRow));
Здесь SizeOf(TRow) равно 5. Т. е. вы не выделяете память под RowData ?
← →
Сергей М. © (2007-02-02 13:22) [6]
> TByteArray; // array of byte
А зачем ты использовал идентификатор TByteArray ? Он уже определен в SysUtils как статический массив !
← →
Сергей М. © (2007-02-02 13:24) [7]+ см. palva © (02.02.07 13:22) [5]
← →
Arm79 © (2007-02-02 13:25) [8]правильно.
тип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));
← →
Arm79 © (2007-02-02 13:26) [9]
> Сергей М. © (02.02.07 13:22) [6]
>
> > TByteArray; // array of byte
>
>
> А зачем ты использовал идентификатор TByteArray ? Он уже
> определен в SysUtils как статический массив !
SysUtils в модулях идет раньше моего, поэтому TByteArray не является статическим и используется мое описане типа
← →
Сергей М. © (2007-02-02 13:28) [10]
> выделяю память равную 5, а потом к этой области памяти дописываю
> кусок
Куда дописываешь-то ? В память, которую ты не выделял ? Это же нонсенс)
← →
Arm79 © (2007-02-02 13:30) [11]тогда просьба )
как выделить память под поле RowData?
← →
Anatoly Podgoretsky © (2007-02-02 13:31) [12]> Arm79 (02.02.2007 13:25:08) [8]
> то есть выделяю память равную 5, а потом к этой области памяти дописываю кусок
Зачем ты так делаешь?
← →
Сергей М. © (2007-02-02 13:32) [13]
> я лично вижу в памяти как
> BIIIIDDDDDD...DDDDD // byte, integer, data
>
Все правильно.
Своим "дописанным" DDDDDD...DDDDD ты изгадил содержимое некоего участка памяти, тебе не принадлежащего. И вполне возможно, что в этом участке лежат внутренние данные менеджера памяти, ты их беспардонно покоцал, поэтому менеджер и дает тебе отлуп в виде AV.
← →
Anatoly Podgoretsky © (2007-02-02 13:34) [14]> () []
> как выделить память под поле RowData?
Это не имеет смысла дела, поскольку данное поле нулевой длины.
← →
Arm79 © (2007-02-02 13:34) [15]
> Anatoly Podgoretsky © (02.02.07 13:31) [12]
> > Arm79 (02.02.2007 13:25:08) [8]
>
> > то есть выделяю память равную 5, а потом к этой области
> памяти дописываю кусок
>
> Зачем ты так делаешь?
потому что руки кривые
поэтому и на форуме, уму разуму набираюсь
← →
Сергей М. © (2007-02-02 13:55) [16]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:59) [17]Большое спасибо, не думал, что пойдете на трату своего времени для демонстрации )
Мне был важен принцип, дальше я сам сделал бы. У вас очень интересная реализация, приму на заметку.
← →
Сергей М. © (2007-02-02 14:20) [18]
> У вас очень интересная реализация
Что же там интересного ? Тривиальная задача, тривиальный же код ..
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.02.18;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.04 c