Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.02.18;
Скачать: CL | DM;

Вниз

выделение памяти с ошибкой   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.048 c
4-1159539919
Dmitry_177
2006-09-29 18:25
2007.02.18
Кнопка на API


3-1164260869
ValexWeb
2006-11-23 08:47
2007.02.18
Как с помощью компоненты TABLE узнать номер текущей отображаемой


15-1169562476
default
2007-01-23 17:27
2007.02.18
Можно ли в .NET малой кровью получить регион


2-1170051426
=Teddy=
2007-01-29 09:17
2007.02.18
Приложение по умолчанию для определенного файла


2-1169820865
Destroyer
2007-01-26 17:14
2007.02.18
Утечка памяти при использовании TStrings