Главная страница
    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.49 MB
Время: 0.041 c
10-1129708059
SupKlo
2005-10-19 11:47
2007.02.18
Как передать картинку с клиента на сервер через DCOM


1-1166871574
kroner
2006-12-23 13:59
2007.02.18
Почему FindFirst возвращает не ноль?


3-1164868095
xazan
2006-11-30 09:28
2007.02.18
Как создать программно *.mdb БД


15-1169667249
FIL-23
2007-01-24 22:34
2007.02.18
Коды Хемминга


2-1170418335
Beavercrazy
2007-02-02 15:12
2007.02.18
Закачивается на сайт битый файл





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский