Форум: "Начинающим";
Текущий архив: 2006.06.04;
Скачать: [xml.tar.bz2];
ВнизПроблема при работе с указателями Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.037 c