![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема при работе с указателями [D7, WinXP]
Zilog_ © (2006-05-15 12:59:00)Уважаемые мастера, подскажите, что делаю не так:
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.
KygECHuK (2006-05-15 15:08:00) [1]При работе с типом string происходит работа с 4 байтами до указаного адресса - это длинна строки и еще 4 как поле счетчика ссылок, то есть при вызове в таком виде процедура затрагивает еще 8 байтов до выделеного адресса.
Zilog_ (2006-05-15 14:55:00) [2]
> >>string(pBuffer^):=cmd;
> в данном случае происходит перезапись длинны строки в невыделеную
> область памяти
Почему в невыделенную?
GetMem (pBuffer, DataSize);
Эта строка выделяет память...
KygECHuK (2006-05-15 14:49:00) [3]>>string(pBuffer^):=cmd;
в данном случае происходит перезапись длинны строки в невыделеную область памяти
Сергей М. (2006-05-15 14:35:00) [4]см. справку "Structured types"
Zilog_ (2006-05-15 14:31:00) [5]
> Выдаст только в случае packed record.
Можно уточнить, что такое packed record?
Сергей М. (2006-05-15 14:25:00) [6]
> Тогда, SizeOf(TData) выдаст реальный размер
Выдаст только в случае packedrecord.
> чем будет забита неиспользуемая часть cmd и buffer? Нулями?
А какая разница, чем она будет "забита" ?
Ты же ведь передаешь размер используемой части !
Zilog_ (2006-05-15 14:19:00) [7]А если жестко задать размеры, например:
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:15:00) [8]
> SizeOf(data) почему-то выдает 4
Потому что Data - это указатель.
> как узнать реальный размер записи?
SizeOf(TData)
Но это в случае с твоей структурой бессмысленно.
Zilog_ (2006-05-15 14:10:00) [9]
SizeOf(data)почему-то выдает 4, как узнать реальный размер записи?
Сергей М. (2006-05-15 14:08:00) [10]
> будет ли он равен
Не будет.
Zilog_ (2006-05-15 14:08:00) [11]просто дальше:
Socket.sendBuff(data^, DataSize)
Какой должен быть DataSize?
Zilog_ (2006-05-15 14:06:00) [12]Сейчас закралась мысль использовать запись типа:
Tdata = record
DataSize:integer; // размер структуры
CmdSize:integer; //размер команды Length(cmd)
BufferSize:integer; //размер блока данных
cmd:string;//команда
buffer:pChar;//блок данных
end;
Только вот вопрос, как узнать реальный размер этой записи, будет ли он равен DataSize=Length(Cmd)+6+BufferSize
Сергей М. (2006-05-15 14:00:00) [13]Передавать указатели бессмысленно.
Плохиш (2006-05-15 13:56:00) [14]
> Не канает этот кусок кода:
>
> string(pBuffer^):=cmd
copy
Zilog_ (2006-05-15 13:50:00) [15]
> Можно увидеть попытку обращения?
> Хотя телепатор уже сказал, что объект типа TServerVoice
> не создан.
Не канает этот кусок кода:
string(pBuffer^):=cmd
Плохиш (2006-05-15 13:46:00) [16]
> При попытке обращения к этой функции получаю Access violation.
Можно увидеть попытку обращения?
Хотя телепатор уже сказал, что объект типа TServerVoice не создан.
Zilog_ (2006-05-15 13:45:00) [17]Как правильно выделить память для этой записи:
var
Data:^TData
....
New(Data)
или
GetMem(Data, DataSize)
Zilog_ (2006-05-15 13:40:00) [18]Дело в том, что пытаюсь решить проблемы с передачей и приемом пакетов с учетом их возможной склейки и фрагментации, по этому есть определенная структура передаваемых данных: первые два байта размер передаваемых данных, вторые два байта размер передаваемой команды (функ-ция Length), следующие два байта размер передаваемой доп. информации, дольше комманда: стринг и дополнительные данные.
А в данной строке пытаюсь расчитать размер структуры...
Сейчас закралась мысль использовать запись типа:
Tdata = record
DataSize:integer;
CmdSize:integer;
BufferSize:integer;
cmd:string;
buffer:pChar;
end;
Сергей М. (2006-05-15 13:31:00) [19]
> DataSize:=BufferSize+ 6+Length(cmd);
Что за 6?
Почему не доверяешь компилятору расчеты размеров, смещений и пр. ?
Zilog_ (2006-05-15 13:26:00) [20]Нет, при вызове процедуры SendVoiceMessage - получаю Access violation