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

Вниз

Проблема при работе с указателями   Найти похожие ветки 

 
Zilog_ ©   (2006-05-15 12:59) [0]

Уважаемые мастера, подскажите, что делаю не так:

type
 TVoice = record
 Data:pointer; //ññûëêà íà äàííûå
 DataSize:integer;
 id:integer;
 FreeIt: boolean;  
 end;

.......

procedure TServerVoice.SendVoiceMessage(cmd:string; const buffer; BufferSize:integer; id:integer);
var
pInt:^Integer;
pBuffer:pointer;
Voice:TVoice;
DataSize:integer;
begin
DataSize:=BufferSize+6+Length(cmd);
GetMem (pBuffer, DataSize);
Voice.Data:=pBuffer;

pBuffer:=ptr(Cardinal(pBuffer)+6);
string(pBuffer^):=cmd;
pBuffer:=ptr(Cardinal(pBuffer)+length(cmd));
pChar(pBuffer^):=pChar(Buffer);

pInt:=Voice.Data;
pInt^:=DataSize;
Inc(pInt);
pInt^:=Length(cmd);
Inc(pInt);
pInt^:=BufferSize;
end;


При попытке обращения к этой функции получаю Access violation.


 
Zilog_ ©   (2006-05-15 13:02) [1]

Деббагер вылетает на первой попытке записи cmd: string  в память, причем приращение указателя проходит норамльно


 
Плохиш ©   (2006-05-15 13:25) [2]


> При попытке обращения к этой функции получаю Access violation.

Что отладчик отказывается транслировать эту функцию?


 
Zilog_ ©   (2006-05-15 13:26) [3]

Нет, при вызове процедуры SendVoiceMessage - получаю Access violation


 
Сергей М. ©   (2006-05-15 13:31) [4]


> DataSize:=BufferSize+6+Length(cmd);


Что за 6 ?

Почему не доверяешь компилятору расчеты размеров, смещений и пр. ?


 
Zilog_ ©   (2006-05-15 13:40) [5]

Дело в том, что пытаюсь решить проблемы с передачей и приемом пакетов с учетом их возможной склейки и фрагментации, по этому есть определенная структура передаваемых данных: первые два байта размер передаваемых данных, вторые два байта размер передаваемой команды (функ-ция Length), следующие два байта размер передаваемой доп. информации, дольше комманда: стринг и дополнительные данные.

А в данной строке пытаюсь расчитать размер структуры...

Сейчас закралась мысль использовать запись типа:
Tdata = record
DataSize:integer;
CmdSize:integer;
BufferSize:integer;
cmd:string;
buffer:pChar;
end;


 
Zilog_ ©   (2006-05-15 13:45) [6]

Как правильно выделить память для этой записи:

var
Data:^TData
....
New(Data)

или

GetMem(Data, DataSize)


 
Плохиш ©   (2006-05-15 13:46) [7]


> При попытке обращения к этой функции получаю Access violation.

Можно увидеть попытку обращения?
Хотя телепатор уже сказал, что объект типа TServerVoice не создан.


 
Zilog_ ©   (2006-05-15 13:50) [8]


> Можно увидеть попытку обращения?
> Хотя телепатор уже сказал, что объект типа TServerVoice
> не создан.


Не канает этот кусок кода:

string(pBuffer^):=cmd


 
Плохиш ©   (2006-05-15 13:56) [9]


> Не канает этот кусок кода:
>
> string(pBuffer^):=cmd

copy


 
Сергей М. ©   (2006-05-15 14:00) [10]

Передавать указатели бессмысленно.


 
Zilog_ ©   (2006-05-15 14:06) [11]

Сейчас закралась мысль использовать запись типа:
Tdata = record
DataSize:integer; // размер структуры
CmdSize:integer; //размер команды Length(cmd)
BufferSize:integer; //размер блока данных
cmd:string;//команда
buffer:pChar;//блок данных
end;

Только вот вопрос, как узнать реальный размер этой записи, будет ли он равен DataSize=Length(Cmd)+6+BufferSize


 
Сергей М. ©   (2006-05-15 14:08) [12]


> будет ли он равен


Не будет.


 
Zilog_ ©   (2006-05-15 14:08) [13]

просто дальше:
Socket.sendBuff(data^, DataSize)
Какой должен быть DataSize?


 
Zilog_ ©   (2006-05-15 14:10) [14]

SizeOf(data) почему-то выдает 4, как узнать реальный размер записи?


 
Сергей М. ©   (2006-05-15 14:15) [15]


> SizeOf(data) почему-то выдает 4


Потому что Data - это указатель.


> как узнать реальный размер записи?


SizeOf(TData)

Но это в случае с твоей структурой бессмысленно.


 
Zilog_ ©   (2006-05-15 14:19) [16]

А если жестко задать размеры, например:
Tdata = record
DataSize:integer; // размер структуры
CmdSize:integer; //размер команды Length(cmd)
BufferSize:integer; //размер блока данных
cmd:string(30);//команда
buffer:pChar(4096);//блок данных
end;


Тогда, SizeOf(TData) выдаст реальный размер, если да, то чем будет забита неиспользуемая часть cmd и buffer? Нулями?


 
Сергей М. ©   (2006-05-15 14:25) [17]


> Тогда, SizeOf(TData) выдаст реальный размер


Выдаст только в случае packed record.


> чем будет забита неиспользуемая часть cmd и buffer? Нулями?


А какая разница, чем она будет "забита" ?
Ты же ведь передаешь размер используемой части !


 
Zilog_ ©   (2006-05-15 14:31) [18]


> Выдаст только в случае packed record.


Можно уточнить, что такое packed record?


 
Сергей М. ©   (2006-05-15 14:35) [19]

см. справку "Structured types"


 
KygECHuK ©   (2006-05-15 14:49) [20]

>>string(pBuffer^):=cmd;
в данном случае происходит перезапись длинны строки в невыделеную область памяти


 
Zilog_ ©   (2006-05-15 14:55) [21]


> >>string(pBuffer^):=cmd;
> в данном случае происходит перезапись длинны строки в невыделеную
> область памяти

Почему в невыделенную?
GetMem (pBuffer, DataSize);
Эта строка выделяет память...


 
KygECHuK ©   (2006-05-15 15:08) [22]

При работе с типом string происходит работа с 4 байтами до указаного адресса - это длинна строки и еще 4 как поле счетчика ссылок, то есть при вызове в таком виде процедура затрагивает еще 8 байтов до выделеного адресса.



Страницы: 1 вся ветка

Текущий архив: 2006.06.04;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.045 c
5-1132723716
ККВ
2005-11-23 08:28
2006.06.04
Не запускается программа в режиме отладки


2-1147794206
Laymer
2006-05-16 19:43
2006.06.04
Перемещение изображения


2-1147878626
Sapan
2006-05-17 19:10
2006.06.04
Создание процедуры в Delphi7


15-1146834675
Jeer
2006-05-05 17:11
2006.06.04
Еще один Gesserex ?


2-1147470240
Призрак
2006-05-13 01:44
2006.06.04
COM-порт