Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
1-1167139043
DelphiLexx
2006-12-26 16:17
2007.02.18
Присоединить статическую библиотеку *.lib


2-1169955441
vegarulez
2007-01-28 06:37
2007.02.18
Как правильно из DBGridColumnMoved вызвать DBGridCellClick?


2-1170320253
Neket
2007-02-01 11:57
2007.02.18
Query


2-1170084942
Квэнди
2007-01-29 18:35
2007.02.18
Сообщение форме


2-1170065544
GrayFace
2007-01-29 13:12
2007.02.18
Не показывать конструктор родителя при overload нутом своем?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский