Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.057 c
2-1147752004
rubey
2006-05-16 08:00
2006.06.04
Ввод через DBGRID


15-1147090760
Alexis
2006-05-08 16:19
2006.06.04
Трансляция хоккейного матча Россия-Беларусь


2-1147681226
evg123
2006-05-15 12:20
2006.06.04
Печать DBGrid a


1-1146036679
leonidus
2006-04-26 11:31
2006.06.04
Как в TListView отобразить больше 32000 записей


2-1147682714
Сергей И
2006-05-15 12:45
2006.06.04
Индексы





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