|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Что такое "Переполнение кипы"? И как ее убрать???
Я пишу игрушку с помощью DelphiX. Но вот однажды компилятор не обнаружив ошибок компилировал мою игру появилось окно в котором сказано про какое-то там исключение и "Stack overload" (в сократ персональный это перевелось как "переполнение кипы"). Что это, и как этого избежать???
http://forceway.ru/ |
#2
|
||||
|
||||
Вот фото:
Вот фото ошибки:
http://forceway.ru/ |
#3
|
|||
|
|||
Переполнение стека происходит, как правило, при большом количестве рекурсивных вызовов. Т.е. один и тот же кусок программы вызывает сам себя и в нем вовремя не наступает условие выхода.
Такое же может быть и при ситуации, когда одна процедура вызывает другую, та в свою очередь вызывает вызвавшую ее. Третья причина ошибки (сейчас крайне редкая), когда глубина выполнения процедур слишком велика (т.е. процедура вызывает другую, та третью, третья четвертую и т.д.) Могут быть и другие причины, но без кода программы выявить их не возможно. Надо проверить свою программу на рекурсивные вызовы (эта штука коварная и иногда такое заметить трудно) или внимательно посмотреть, нет ли слишком глубокой вложенности вызова процедур. Не забывайте делать резервные копии Последний раз редактировалось san-46, 18.06.2008 в 20:36. |
#4
|
||||
|
||||
А как проверить?
http://forceway.ru/ |
#5
|
|||
|
|||
Для программера только один путь - запуск программы в отладке. Но вначале проанализировать код и попытаться примерно определить где может быть засада.
Кстати, ведь ошибка происходит, следовательно в отладке можно определить на каких строках. Посмотреть окно "Call Stack", где можно увидеть предыдущие шаги - откуда ошибка пришла. Не забывайте делать резервные копии Последний раз редактировалось san-46, 18.06.2008 в 20:44. |
#6
|
||||
|
||||
Я кажется нашел ошибку, но у меня весь код получается что на ошибки...
Ошибка в событии FormCreate. http://forceway.ru/ |
#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
|
||||
|
||||
Не подскажете... а как исправить?
http://forceway.ru/ |
#9
|
||||
|
||||
Пытюсь сам, но...
http://forceway.ru/ |
#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 переменные уничтожается после конца процедуры. http://forceway.ru/ |
#13
|
||||
|
||||
Они локальные, значит их надо добавить в глобальные?
http://forceway.ru/ |
#14
|
|||
|
|||
Да, конечно их надо переместить в объявление класса TMainForm и не забыть уничтожить в деструкторе (OnDestroy).
Не забывайте делать резервные копии Последний раз редактировалось san-46, 18.06.2008 в 21:50. |
#15
|
||||
|
||||
Т.е. получается, что все действия надо проводить с переменными PS1 и PS2? А не с TPlayerSprite1 и TPlayerSprite2?
http://forceway.ru/ |