Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
26-01-2006 22:27 | Комментарий к предыдущим ответам
>>To Антон Григорьев
Отправил на подводные камни, спасибо за совет
25-01-2006 01:44 | Комментарий к предыдущим ответам
Kealon:
Для описания таких ситуаций здесь существует раздел "Подводные камни" http://www.delphikingdom.com/stones
Будем очень благодарны, если вы напишете туда заметку об этом эффекте.
с const по осторожнее желательно обращаться, там несколько интересно получается с передачей интерфейсов, вот приблизительно какую мулю я замутил и потом долго искал ошибку
procedure proc1(f:IMy);
begin
f.fly;
end;
procedure proc2(f:IMy);
begin
f.fly2;
end;
procedure test(const f:IMy);
begin
proc1(f);//после этого вызова объект удаляется
proc2(f);
end;
...
test(TMy.Create);
В Паскале под Dos, передача большой структуры вместо указателя на нее зачастую вызывала переполнение стека, он ведь не резиновый. В Windows эта проблема менее актуальна, но хороший стиль программирования - это важный элемент.
Есть такая область памяти - стек, которая используется, в т.ч., и для передачи параметров в процедуры. Если параметр передаётся по значению, при вызове процедуры он копируется в стек. В первом случае копируется вся структура целиком, во втором - только указатель (4 байта). Выигрыш есть, но на современных процессорах в большинстве случаев он незаметен: если речь идёт о нескольких дестяках байт, то копирование - достаточно быстрая операция.
С указателем можно и не заморачиваться, а объявить параметр константным:
procedure FigZnaet(const Data: TStructure);
Тогда для длинных параметров компилятор автоматически будет помещать в стек указатель, а не саму структуру.
P.S. По умолчанию в Delphi применяется модель вызова register, в которой часть параметров передаётся не через стек, а через регистры. В этом случае при вызове для любых типов параметров (var, const или параметр-значение) в регистр eax будет помещаться адрес структуры. Но сам код функции без использования const будет таков, что в начале её работы параметр всё-таки скопируется в стек.
Всегда - не всегда - вопрос спорный.
Ответ на вопрос почему - попробуй сравнить SizeOf(TStructure) и SizeOf(PStructure). Полученное значение (он не понмю выравненное значение дает SizeOf или нет, если нет, то округлить до разрадности стека) резеривируется в стеке всяк раз когда ты передаешь параметр. Для пущщего ужасания поставь брик поинт в каком нить событии по какому нить маусу и посмотри Call Stack этого события... а теперь представь сколько все вызовы могли бы отгебать в стеке, передавай в них значения по структуре.
Тоже самое относится к строкам
В делфях разименование указалелей допускается без использования "^" что с одной стороны радует, ибо мне тка более читабельно, но может запутать новичка.
Если лениво возиться с указателями, можно структуры передавать var или const параметры (неявно будет передан указатель)
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.