![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
|
Я пишу игрушку с помощью DelphiX. Но вот однажды компилятор не обнаружив ошибок компилировал мою игру появилось окно в котором сказано про какое-то там исключение и "Stack overload" (в сократ персональный это перевелось как "переполнение кипы"). Что это, и как этого избежать???
|
|
#2
|
||||
|
||||
|
Вот фото ошибки:
|
|
#3
|
|||
|
|||
|
Переполнение стека происходит, как правило, при большом количестве рекурсивных вызовов. Т.е. один и тот же кусок программы вызывает сам себя и в нем вовремя не наступает условие выхода.
Такое же может быть и при ситуации, когда одна процедура вызывает другую, та в свою очередь вызывает вызвавшую ее. Третья причина ошибки (сейчас крайне редкая), когда глубина выполнения процедур слишком велика (т.е. процедура вызывает другую, та третью, третья четвертую и т.д.) Могут быть и другие причины, но без кода программы выявить их не возможно. Надо проверить свою программу на рекурсивные вызовы (эта штука коварная и иногда такое заметить трудно) или внимательно посмотреть, нет ли слишком глубокой вложенности вызова процедур. Последний раз редактировалось san-46, 18.06.2008 в 20:36. |
|
#4
|
||||
|
||||
|
А как проверить?
|
|
#5
|
|||
|
|||
|
Для программера только один путь - запуск программы в отладке. Но вначале проанализировать код и попытаться примерно определить где может быть засада.
Кстати, ведь ошибка происходит, следовательно в отладке можно определить на каких строках. Посмотреть окно "Call Stack", где можно увидеть предыдущие шаги - откуда ошибка пришла. Последний раз редактировалось san-46, 18.06.2008 в 20:44. |
|
#6
|
||||
|
||||
|
Я кажется нашел ошибку, но у меня весь код получается что на ошибки...
Ошибка в событии FormCreate. |
|
#7
|
|||
|
|||
|
В этом коде рекурсивный вызов метода Create.
Код:
constructor TPlayerSprite1.Create(AParent: TSprite);
begin
with TPlayerSprite1.Create(MainForm.Dxspriteengine.Engine) do begin
PixelCheck := True;
Image := MainForm.DXImageListAnime1.Items.Find('obichniy');
x:=10;
y:=200;
Width := Image.Width;
Height := Image.Height;
end;
end;Последний раз редактировалось san-46, 18.06.2008 в 21:18. |
|
#8
|
||||
|
||||
|
Не подскажете... а как исправить?
![]() |
|
#9
|
||||
|
||||
|
Пытюсь сам, но...
|
|
#10
|
|||
|
|||
|
Код:
constructor TPlayerSprite1.Create(AParent: TSprite);
begin
PixelCheck := True;
Image := MainForm.DXImageListAnime1.Items.Find('obichniy');
x:=10;
y:=200;
Width := Image.Width;
Height := Image.Height;
end;Код:
procedure TMainForm.FormCreate(Sender: TObject); var PS1 : TPlayerSprite1; PS2 : TPlayerSprite2; begin PS1 := TPlayerSprite1.Create(Dxspriteengine.Engine); PS2 := TPlayerSprite2.Create(Dxspriteengine.Engine); end; |
|
#11
|
|||
|
|||
|
А зачем объявлять два совершенно одинаковых класса (TPlayerSprite1 и TPlayerSprite2)? Когда можно объявить один и сделать два (при необходимости, сколько угодно) экземпляра этого класса.
Код:
procedure TMainForm.FormCreate(Sender: TObject); var PS1, PS2 : TPlayerSprite; begin PS1 := TPlayerSprite.Create(Dxspriteengine.Engine); PS2 := TPlayerSprite.Create(Dxspriteengine.Engine); end; Если TPlayerSprite визуальный компонент тогда оправдано, но опять же, зачем тогда его создавать в FormCreate, если они автоматом создаются при запуске программы. Последний раз редактировалось san-46, 18.06.2008 в 21:48. |
|
#12
|
||||
|
||||
|
Цитата:
Дело в том, что PS1 и PS2 переменные уничтожается после конца процедуры. |
|
#13
|
||||
|
||||
|
Они локальные, значит их надо добавить в глобальные?
|
|
#14
|
|||
|
|||
|
Да, конечно их надо переместить в объявление класса TMainForm и не забыть уничтожить в деструкторе (OnDestroy).
Последний раз редактировалось san-46, 18.06.2008 в 21:50. |
|
#15
|
||||
|
||||
|
Т.е. получается, что все действия надо проводить с переменными PS1 и PS2? А не с TPlayerSprite1 и TPlayerSprite2?
|