Главная страница
    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.045 c
8-1151309796
RealGanj
2006-06-26 12:16
2007.02.18
Анимации в тексте


15-1169624052
Hero
2007-01-24 10:34
2007.02.18
Помогите найти компонет типа richedit но с вставкой битмапов


15-1170073128
Nic (from SAF)
2007-01-29 15:18
2007.02.18
Что бы почиатать о теории


2-1170149118
myaucher
2007-01-30 12:25
2007.02.18
Использование Data Module


2-1170416926
Garacio
2007-02-02 14:48
2007.02.18
Как в Delphi получить букву системного диска?





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