Срабатывает обработчик, в нем вызывается Next
, это вызывает срабатывание обработчика… и так до бесконечности, пока не забивается стек.
Как костыль — можно завести булеву переменную для блокировки обработчика: в начале обработчика проверять флаг, если его значение false
— выставлять в true
и выполнять остальную часть, в противном случае (если true
) — выходить. Тогда при попытке повторно зайти в обработчик его выполнение тут же прекратится. Переменная должна быть объявлена не в самом обработчике, а выше (в модуле, в классе).
Другой костыль — в начале обработчика, выставлять вашему набору данных AfterScroll := nil
, а в конце — возвращать обратно AfterScroll := ...
.
В обоих вариантах код обработчика стоит завернуть в try-finally
и разблокировку выполнять в блоке finally
. В противном случае, при возникновении исключения, вы останетесь без обработчика.
А вообще лучше разобраться, что у вас там с вычисляемым полем.
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;
If you are using a thread(not main ex:sock connection) and main thread so they share the same stack. Solve this way :just create a thread with its own stack for each connection.
Problem > each call you do it call stack for frame (the shared one so big problem)
example you call proc aa(a,b:integer) for example on calling always the same function or different one ;
You have a socket thread running, and onconnect you call proc a; and stays doing something it take 5 secs.
if some one connects before the on connect close connection (release stack).
You have the 2 connected clients (2 diff stack frames with each different data)
stack
push a,b (integer); Values 5,10 — from 1 conn
push a,b (integer); Values 7,3 — from 2 conn
if the onconnect call the functions a(5,10) and stays doing something for about 5 sec.
and some one connect to the server socket again it call on connect again.
The stack olds the first call frame yet didn’t went out of proc. So didn’t pop a,b from (5,10)
It is more complex than this if you proc call again then it will override data on the 2 frame (local proc variable of 2 connection) so when 2 connection get data from stack is already overridden by other info for sure. so it will do incorrect behavior.
When first connection is down will pop a,b but 7,3 (from second connection) and not the 5,10 it saved. so it will stack overflow not on the moment but later with the program running and stack release errors you’ll get eventually a $FFFFFFFF $SP
stack. so it will try to $FFFFFFAA
when you call a function so is bigger than ya stack ex: $M 65536
and not 4 gigabytes as $FFFFFFAA
.
jaguarchuk 0 / 0 / 0 Регистрация: 25.03.2012 Сообщений: 20 |
||||
1 |
||||
19.06.2012, 23:03. Показов 8381. Ответов 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 |
474 / 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 |
@James Steel
keep in mind that many «weird» errors as you say, especially when porting old projects to new IDEs, and vice versa, have a lot to do with the project settings files!
Thus, whenever porting a project to another IDE, new or old, try to proceed as follows:
- In the new IDE, create a new project
- Delete the form that is created automatically, normally «Form1»
- Now, add all the files (forms, units, etc…) from the old project to this «new» project.
- Now make the necessary settings in «Project — Options…» and in any other necessary places!
- Now save this «new» project in a suitable folder for your new IDE. — use a folder specific for this IDE, ex.: ..\RAD10\prjRAD10 …. ..\RAD11\prjRAD11 ….
- That’s it, if this was the problem, then it won’t be anymore!
And, finally, you will have a new project preserving the old project, however, using the same files (forms, units, etc…) as you would expect. Now you can make your desired changes, always keeping in mind that, you are developing for two or more IDEs, so use the «compiler directives» when necessary to separate the code pertinent and particular to each IDE involved in your project!