jaguarchuk 0 / 0 / 0 Регистрация: 25.03.2012 Сообщений: 20 |
||||
1 |
||||
19.06.2012, 23:03. Показов 8230. Ответов 5 Метки нет (Все метки)
Ну ни как не хочет работать
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
19.06.2012, 23:03 |
Ответы с готовыми решениями: Ошибка stack overflow Stack is overflow в игре ошибка Overflow Stack Stack overflow в чате 5 |
421 / 351 / 19 Регистрация: 14.05.2012 Сообщений: 1,437 |
|
19.06.2012, 23:23 |
2 |
Что именно не работает?Выдает ошибку, или еще что?…
0 |
0 / 0 / 0 Регистрация: 25.03.2012 Сообщений: 20 |
|
19.06.2012, 23:34 [ТС] |
3 |
Что именно не работает?Выдает ошибку, или еще что?… ошибка же stack overflow
0 |
421 / 351 / 19 Регистрация: 14.05.2012 Сообщений: 1,437 |
|
19.06.2012, 23:41 |
4 |
ошибка Overflow Stack смотри здесь Добавлено через 36 секунд
0 |
429 / 337 / 36 Регистрация: 31.05.2011 Сообщений: 1,156 |
|
19.06.2012, 23:41 |
5 |
Ошибка видимо в другом месте кода
0 |
Одиночка 3943 / 1868 / 337 Регистрация: 16.03.2012 Сообщений: 3,880 |
||||
20.06.2012, 07:53 |
6 |
|||
Скорее всего в строке 12 выложенного кода компилятор интерпретирует p как функцию и происходит рекурсивное обращение к самой себе. Пиши так:
3 |
The default maximum stack size for a thread is 1 MB. The three local variables of Button1Click
total 131,070 + 65,535 * 4 + 65,535 * 8 = 917,490 bytes. When you call getProcessedData
, you pass the parameter by value, which means that the function makes a local copy of the parameter on the stack. That adds SizeOf(TRawInts)
= 262,140 bytes to bring the stack to at least 1,179,630 bytes, or about 1.1 MB. There’s your stack overflow.
You can reduce the stack use by passing the TRawInts
array by reference instead. Then the function won’t make its own copy. Zdravko’s answer suggests using var
, but since the function has no need to modify the passed-in array, you should use const
instead.
function getProcessedData(const rawInts: TRawInts): TProcessedData;
Naively, we might expect the tempData
and Result
variables in getProcessedData
to occupy additional stack space, but in reality, they probably won’t. First, large return types typically result in the compiler changing the function signature, so it would act more like your function were declared with a var
parameter instead of a return value:
procedure getProcessedData(rawInts: TRawInts; var Result: TProcessedData);
Then the call is transformed accordingly:
getProcessedData(rawInts, processedData);
Thus, Result
doesn’t take up any more stack space because it’s really just an alias for the variable in the caller’s frame.
Furthermore, sometimes the compiler recognizes that an assignment at the end of your function, like Result := tempData
, means that tempData
doesn’t really need any space of its own. Instead, the compiler may treat your function as though you had been writing directly into Result
all along:
begin
scaleFactor := 0.01;
for i := 0 to 65534 do
Result[i] := rawInts[i] * scaleFactor;
end;
However, it’s best not to count on the compiler to make those sorts of memory-saving changes. Instead, it’s better not to lean so heavily on the stack in the first place. To do that, you can use dynamic arrays. Those will move the large amounts of memory out of the stack and into the heap, which is the part of memory used for dynamic allocation. Start by changing the definitions of your array types:
type
TRawData = array of Byte;
TRawInts = array of Integer;
TProcessedData = array of Double;
Then, in your functions that return those types, use SetLength
to assign the length of each array. For example, the function we’ve seen already might go like this:
function getProcessedData(const rawInts: TRawInts): TProcessedData;
var
i: Integer;
scaleFactor: Double;
begin
Assert(Length(rawInts) = 65535);
SetLength(Result, Length(rawInts));
scaleFactor := 0.01;
for i := 0 to High(rawInts) do
Result[i] := rawInts[i] * scaleFactor;
end;
Срабатывает обработчик, в нем вызывается Next
, это вызывает срабатывание обработчика… и так до бесконечности, пока не забивается стек.
Как костыль — можно завести булеву переменную для блокировки обработчика: в начале обработчика проверять флаг, если его значение false
— выставлять в true
и выполнять остальную часть, в противном случае (если true
) — выходить. Тогда при попытке повторно зайти в обработчик его выполнение тут же прекратится. Переменная должна быть объявлена не в самом обработчике, а выше (в модуле, в классе).
Другой костыль — в начале обработчика, выставлять вашему набору данных AfterScroll := nil
, а в конце — возвращать обратно AfterScroll := ...
.
В обоих вариантах код обработчика стоит завернуть в try-finally
и разблокировку выполнять в блоке finally
. В противном случае, при возникновении исключения, вы останетесь без обработчика.
А вообще лучше разобраться, что у вас там с вычисляемым полем.
Форум программистов Vingrad
Модераторы: Snowy, Alexeis, MetalFan |
Поиск: |
|
Опции темы |
Uxas |
|
||
Новичок Профиль Репутация: нет
|
Прошу подсказать, изучаю DelphiX четвертый день, решил просто потренироваться — квадратом бегаю по экрану, в разных местах появляются еще почти такие же но другого класса, и хотел сделать так чтобы при столкновении происходило изменение координат у последних(вначале хотел сделать что то типа змейки) в общем всё как бы ничего и если пишу в столконовении Dead то они уничтожаются, но вот если пишу в DoMove главного квадрата сохранение координат в две переменные(x1:=x; y1:=y; ) а потом в DoMove квадратов которые появляются пишу x:=x1; y:=y1; в запущеной игре при столкновении вылазит ошибка «Stack Overflow» и игра закрывается немогу понять в чем дело. Может и это не будет походить на змейку и что то подобное ей а просто квадраты будут лепиться друг ко другу но меня интересует откуда берется эта ошибка и как от нее избавиться. Ну если кто то подскажет как написать змейку буду более благодарен. |
||
|
|||
~FoX~ |
|
||
НЕ рыжий!!! Профиль
Репутация: 2
|
Uxas, Код в студию, а то все телепаты сегодня с похмелья… ———————
|
||
|
|||
Uxas |
|
||
Новичок Профиль Репутация: нет
|
Код в студии
|
||
|
|||
Bitter |
|
||
Опытный лентяй Профиль
Репутация: 6
|
Отличный код, ничего не понятно.. что за функции DoMove, Collision. ну вобщем ставишь брекпоинт где нить на inherited, жмешь F7 и смотришь куда заходит. Stack Overflow это когда курсор бесконечно заходит в одну или несколько функций, и не может выйти из за того, что либо одна функция вызывает сама себя либо несколько функций вызывают одна другую и наоборот |
||
|
|||
~FoX~ |
|
||
НЕ рыжий!!! Профиль
Репутация: 2
|
А почему инхеритед в начале? ———————
|
||
|
|||
|
Правила форума «Delphi: Звук, графика и видео» | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делится вскрытыми компонентами
FAQ раздела лежит здесь! Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) |
0 Пользователей: |
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема » |
|
|
|
Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как «свернуть» программу в трей.
3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
… (продолжение следует) …
Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.
Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка — 60 дней. Последующие попытки бан.
Мат в разделе — бан на три месяца…
Сообщение «Stack overflow» (исключение EStackOverflow)
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Full Member Рейтинг (т): 2 |
Добрый день! Подскажите пожалуйста, когда может появляться сообщение «Stack overflow» (исключение EStackOverflow)? with DataModule1.UmzDpd do begin if Active=True then begin First; while Eof<>True do begin Edit; if FieldByName(‘НаличиеРСТ’).AsBoolean=True then FieldByName(‘НаличРСТ’).AsString:= ‘Да’ else FieldByName(‘НаличРСТ’).AsString:= ‘Нет’; Next; end; First; end; end; Здесь присваивается значение вычисляемому полю (оно исчезает в гриде всякий раз, как переходишь на другую строку). Метод Post не вызываю. т.к. мне не нужно отправлять в БД, нужно только чтобы показывалось в гриде. Я использую LockType=ItBatchOptimistic (тогда данные в БД отсылаются только методом TADODataSet.UpdateBatch). В чем может быть ошибка? |
MBo |
|
Наиболее вероятна причина — бесконечная рекурсия, в данном случае некие вызовы методов (Next?) внутри обработчика могут косвенно приводить к вызову этого же обработчика |
Leklerk |
|
Full Member Рейтинг (т): 2 |
Да, спасибо, так и оказалось, проблема решена. |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- Delphi: Общие вопросы
- Следующая тема
[ Script execution time: 0,0236 ] [ 16 queries used ] [ Generated: 4.06.23, 11:03 GMT ]