Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Dynamic arrays и TStream


Страницы:   1 2

Grim ©   (2004-11-28 01:00:00) 

Доброго всем времени суток!
У меня возник такой вопрос.
Есть таблица с данными (T), записанная в dynamic array of TActorInfo,
где TActorInfo - рекорд из различного типа данных (Bool, Float, Int).

Таблица пересылается через методы idUDPServer.SendBuffer;
UDPServer.SendBuffer(IPAdress, Port, T[0], SizeOf(TActorInfo)*Length(T));

Теперь на другом конце Я должен получить точно такой же массив Т:

UDPServerUDPRead(Sender: TObject; AData: TStream;ABinding: TIdSocketHandle);
begin
 SetLength(T, 2); //ye допустим я знаю сколько записей там
 Adata.Read(T, SizeOf(TActorInfo)*2);  
end;

После этого обращение к Т вызывает ошибку "память там-то не может быть
считана" (обычная).
Вопрос: что я делаю не так или как это сделать иначе (UDP протокол необходим)?


Суслик   (2004-11-29 11:06:00) [1]


> d[0] - это нулевой элемент массива. Будешь оспаривать?

это значение нулевого элемента массива...

И вообще, не обижайся, если есть на что... Правды в виртуальном общении не найдешь :)

Но дело в том, что pointer(str)^ или pointer(dynarray)^ есть используемый многими путь обращения к данным... При том путь допустимый соглавно текущей документации к языку разработки delphi (выдержку из справки я приводил, она находтися в разделе memory managment). Если смотреть в будущее, то там все равно будут такие подходы, которые не позволят пользовать ни тем, ни другим методом доступа к данным.


Verg   (2004-11-28 19:41:00) [2]


> так нет гарантии, что @(d[0]) также показывает на начало
> данных.


Зачем же искажать мои слова? Точнее приписывать мне того, чего я не говорил?

d[0] - это нулевой элемент массива. Будешь оспаривать?

Если же тебе больше нравится к гландам добираться окольными путями, типа через копчик - это твоя проблема.


Суслик   (2004-11-28 18:58:00) [3]


>  [27] Verg ©   (28.11.04 18:54)


> dynarray[0] - это чистокровный 0-вой элемент массива, безо
> всяких "если".

Вот позвольте, придраться к слову "чистокровный".
В рамках дельфи и того compiler magic, который он сует в код, говорить о чискоровности не приходится. Уж извините.
Как нет гарантии, что pointer(d) будет в будущем показывать на начало данных, так нет гарантии, что @(d[0]) также показывает на начало данных.
Например, это может быть адрес функции доступа к элементу массива. Почему нет? Да шансе изменеия такого рода сущесвенно меньше, чем подход к pointer(d), но они есть.

Если же говорить о сухой практике, то и тот и другой подход будут работать. Дельфи не сможет отказаться от такой реализации массивов. Т.к. я часто видел в чужих компонентах использование pointer...


Verg   (2004-11-28 18:54:00) [4]


> [26] Суслик ©   (28.11.04 18:49)


Я просто скажу свое мнение, просто еще раз

pointer(dynarray)^  - это притянутое за уши преобразование типов, пользуясь знаниями текущей реализации этого типа данных в текущем релизе компилера и runtimelib

dynarray[0] - это чистокровный 0-вой элемент массива, безо всяких "если".

Все.


Суслик   (2004-11-28 18:49:00) [5]


> Verg ©   (28.11.04 18:47) [25]

Ну ладно, ладно - давайте жить дружно.
Собственно давайте подведем итог:

Чем по вашему обращение вида pointer(dynarray)^ хуже dynarray[0]?

Коротко и ясно. Думаю, что все уже сказано - но думаю нас могут читать начинающие, надо для них постараться :))


Verg   (2004-11-28 18:47:00) [6]


> [24] Суслик ©   (28.11.04 18:42)


МЧ. Вы и на самом дело очень болезненно воприниаете.

Вам бы провести лично для себя разбор "полетов в это топике". Для того, просто, чтобы дать себе отчет в том, ктоименно "ввязался" и во что "ввязался".


Суслик   (2004-11-28 18:42:00) [7]


>  [23] Verg ©   (28.11.04 18:40)


> Есть тема, вопрос и я на нее ответил

На вопрос ответили еще в первом посте.
Ты ввязался в спор :)))
Как ты сам сказал, не имеющий предмета.
ЗЫ. Когда в следущий раз кто-то из одноцветных с тобой употребит это слово - будь с ними также вежлив, очень прошу. Нет двойным стандартам.


Verg   (2004-11-28 18:40:00) [8]


> Ладно, хватит, писюлями меряться.


Писюлями? :)))
Есть тема, вопрос и я на нее ответил. Все остальное - это у кого чего болит, тот о том  и говорит..


Суслик   (2004-11-28 18:37:00) [9]


> Но ты-то так и не указал - на чем, собственно, основано
> твое предположение,

Ты шататный хелп дельфи читал?

Может я вчера родился, но описание -4 или -8 в отношении указателя всегда расценивалось, как вмещение относительно указателя

A dynamic-array variable occupies four bytes of memory which contain a pointer to the dynamically allocated array. When the variable is empty (uninitialized) or holds a zero-length array, the pointer is nil and no dynamic memory is associated with the variable. For a nonempty array, the variable points to a dynamically allocated block of memory that contains the array in addition to a 32-bit length indicator and a 32-bit reference count. The table below shows the layout of a dynamic-array memory block.

Offset Contents
–8 32-bit reference-count
–4 32-bit length indicator (number of elements)
0..Length * (size of element) – 1 array elements

(выдержка их хелпа).

Ладно, хватит, писюлями меряться.
Сам же сказал разговор беспредметный.


Игорь Шевченко   (2004-11-28 18:34:00) [10]

Verg ©   (28.11.04 17:48) [9]

Спасибо :) Все гениальное просто :)


Verg   (2004-11-28 18:34:00) [11]

Конечно вырвал.

Dynamic-array variables are implicitlypointers and are managed by the same reference-counting technique used for long strings. To deallocate a dynamic array, assign nil to a variable that references the array or pass the variable to Finalize; either of these methods disposes of the array, provided there are no other references to it. Dynamic arrays of length 0 have the value nil. Do not apply the dereference operator (^) to a dynamic-array variableor pass it to the New or Dispose procedure.

Но ты-то так и не указал - на чем, собственно, основано твое предположение, что pointer(DynArray) указывает на область памяти, где хранятся данные массива, а не, например, управляющая им структура, где среди прочих элементов есть и указатель на память с данными массива.


Суслик   (2004-11-28 18:24:00) [12]


> Do not apply the dereference operator (^) to a dynamic-array variable

уверен, что ты это вырвал из контекста.

В свое время когда дельфи стало возможно откзаться от ^ в отношении указателей, в описании наверняка была такая же фраза. Однако, сомневаюсь, что она что-то значит больше, чем дословный перевод.


Суслик   (2004-11-28 18:22:00) [13]


>  [17] Verg ©   (28.11.04 18:18)

открою тебе секрет, я не пользуюсь динамическими массивами :)))
т.о. я ничего не продполагаю
Все мое участие в данном топике сводится к тому, что я сказал, что есть еще путь. Сомневаюсь, что толькоя по нему хожу


Verg   (2004-11-28 18:18:00) [14]

Мало того, что ты предпологаешь, что переменная типа дин. массив - это указатель на данные(Почему бы?) хранящиеся в этом массиве, так и

Do not apply the dereference operator (^) to a dynamic-array variable....(С) Delphi Help.


Verg   (2004-11-28 18:10:00) [15]


> [15] Суслик ©   (28.11.04 18:04)
>
> >  [14] Verg ©   (28.11.04 18:03)
>
>
> > В любом случае необходимо проверять, что массив не пуст.
>
> в данном конкретном случае да, но если было так:
>
> Adata.Read(pointer(T)^, SizeOf(TActorInfo)*length(T));
>
> то не надо


Спор беспредметен, т.к. ты расчитываешь на то, что виртуальный метод Read у потокапроверит на <>0 Count, который ему передадут. Т.о. собственно к динамич. массивам это не имеет ровно никакого отношения.
В общем слуаче как раз проверять на неноль длину массива.


Суслик   (2004-11-28 18:04:00) [16]


>  [14] Verg ©   (28.11.04 18:03)


> В любом случае необходимо проверять, что массив не пуст.

в данном конкретном случае да, но если было так:

Adata.Read(pointer(T)^, SizeOf(TActorInfo)*length(T));

то не надо


Verg   (2004-11-28 18:03:00) [17]


> [2] Суслик ©   (28.11.04 13:20)
> если не ошибаюсь, то еще так можно
>
> Adata.Read(pointer(T)^, SizeOf(TActorInfo)*2);
>
> Опять же, если не ошибаюсь, то так более правильно для пустого
> массива...


В любом случае необходимо проверять, что массив не пуст.


Суслик   (2004-11-28 18:02:00) [18]


> [11] Verg ©   (28.11.04 17:58)

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


Суслик   (2004-11-28 18:01:00) [19]


>  [11] Verg ©   (28.11.04 17:58)

Я не очень понимаю о чем ты?
Если о av, то данный код был примером того, что i[0] дает range check error в том случае, гда массив пустой. И МОЕ утвержение опровергнутое в [5] о том, что в случае [0] надо проверять наличие элементов имеет смысл.


Verg   (2004-11-28 17:58:00) [20]


> Такой код дает range check error... при всключенном {$R+}
>
> var
>   i: array of integer;
>   d: integer;
> begin
>   move(i[0], d, 4);
> end;


Ну да, теперь осталось проверить ;) что произойдет, если заметить i[0] на pointer(i)^.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо