Показать сообщение отдельно
Старый 10.01.2006, 22:06   #3
AsmLover
 
Сообщений: n/a
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.
 
Ответить с цитированием