Originally posted by impersonalis@Jan 10 2006, 05:14 PM
Код вычурно перегружен отладочными командами и вызовами функций с целью показть уязвимость в действии.
Запустите его в ___ОТЛАДОЧНОМ____ режиме.
И понаблюдайте - сколько раз из 25 b3d докажет что 0<>0.
Теперь отключите отладку и сравните результаты. =)
Положив 2 часа на отладку полностью рабочего кода ( постоянно добавляя отладочные команды - чем ещё более усугублял совё положение) я перепробовал различные версии b3d - все подвержены данной ошибке, которая, судя по всему, заключается в затирании уже используемых пространств памяти.
|
К сожалению, это не баг, а всего лишь неграмотное применение отладчика в примере, который привел Impersonalis. Отлачик в функции TMatrix_Determinant рекурсивно вызывает эту же функцию, что, естественно, неизбежно вызывает исчерпание стека (хорошо еще, что встроенные отладчики имеют свою стековую машину, а то бы вообще все рунуло).
Правильно делать так:
Function TMatrix_Determinant#(M.TMatrix)
SS=M\StringSize
CS=M\CSize
If SS=1 And CS=1
DebugLog "determ ="+M\buffer[0]
Return Float(M\buffer[0])
EndIf
Local DET#=0
For i=1 To SS
MINOR.TMATRIX=TMatrix_minor(M,1,i)
TMD#=TMatrix_Determinant(MINOR)
DebugLog ""+DET+"+"+((-1)^(i+1))+"*"+TMD+"*"+TMatrix_OUT(M,1,i)
DET=DET+(-1)^(i+1)*TMD*Float(TMatrix_OUT(M,1,i))
DebugLog "="+DEt
TMatrix_Delete(MINOR)
Next
DebugLog "determ ="+DET
Return DET
End Function
Теперь никаких ошибок не будет.
В нормальном режиме и дебаггера достаточно ресурсов для своей работы.
Собственно, DebugLog предназначен для формирования строки вывода и имеет буфер строки более 16 Кбайт, это легко проверить с помощью
a$=""
For j=1 To 16000
For i=0 To 9
a$=a$+i
Next
Next
DebugLog a$
WaitKey
Разумеется, ничего не мешает Марку установить и размер стека, не вызывающий проблем в нормальном режиме - для простого блитца он может вообще иметь пару килобайт, а его переполнение ошибки не вызывает (что тоже странно, однако). Правда ошибки в блитце не вызывает и отсутствие вызываемой DLL при динамическом связывании, что не менее странно (а при статическом связывании при этом сразу появится ошибка).
В Help-файле написано, что аргументом DebugLog может быть текстовая переменная, строка, числовое значение. К сожалению, структура справки в целом нечеткая, поэтому трудно судить, запрещалось ли изначально в ней вычисление выражения. Но я пытался без рекурсии свалить стек, но при корректных вычислениях у меня не получилось. Но в любом случае, для вычисления выражений в приведенном Impersonalisom примере ограничивается стековое пространство при рекурсии.
Но есть программы, которые ведут себя странно со включенным Debug , причем DebugLog вообще там не используется, например партикловая система Lotus.