Чтобы вы располагали более полной информацией, позволяющей вам локализовать причину ошибки. Я приведу общий анализ.
Функция
__DBSETLOC располагается в объектном модуле
DBCMD5. Если посмотреть ее исходный код, то единственное, что она делает, это устанавливает кодовый блок
bFor для активной базы данных, если этот кодовый блок был передан в качестве параметра, и возвращает текущее значение блока
bFor.
bFor - это кодовый блок, который формируется, когда вы, например, вызываете команду
LOCATE, указав в ней опцию
FOR. Тогда команда
LOCATE, которая реализована с помощью Clipper функции
__dblocate, то есть
prg модуля, вызывает
__DBSETLOC и передает ей этот кодовый блок
bFor, который соответствует опции команды
LOCATE FOR.
Что может вызвать аварийное завершение функции
__DBSETLOC? Единственное - это вызов из этой функции другой внутренней функции Clipper
__GetGrip из объектного модуля
STACK. Что делает эта функция? Она пытается зафиксировать указатель на кодовый блок в стеке Clipper. Эти фиксированные указатели обрабатываются следующим образом. Если Clipper первый раз пытается фиксировать указатель, то из стека Clipper выделяется некоторый объем памяти для этих указателей. Когда этот объем исчерпывается, то Clipper снова выделяет дополнительную память из стека
Clipper. Когда потребность в фиксированном указателе нет, то Clipper вызывает внутреннюю функцию
__DropGrip. Но память при этом
не возвращается стеку! Просто освобожденные указатели объединяются в односвязный список и помечаются как удаленные. Когда Clipper нужнофиксировать какой-то указатель, то он первым делом просматривает этот список освобожденных указателей.
Не только функция
__DBSETLOC выполняет фиксацию указателей на данные в стеке с помощью
__GetGrip, но и другие функции, например, при работе со строками, или массивами выполняют подобную операцию.
Итак, подытожим. Ошибка возникла в
__DBSETLOC при вызове функции
__GetGrip, которая в свою очередь не нашла места в стеке, чтобы зафиксировать указатель на кодовый блок
bFor. В этом случае вызывается функция
__efault, которая пытается каким-то образом получить память, и если ей не удается, то среди прочих сообщений об ошибке, она выдает сообщение с номером
667, которое вы и получили.
Какой вывод можно сделать из моего анализа? Причиной ошибки является не сама функция
__DBSETLOC, а предыдущий ваш код. аварийное завершение
__DBSETLOC - это лишь следствие переполнения стека другими операциями вашей программы.
То есть сообщенная вами информация не позволяет сделать заключение, какое место в коде вашей программы стало причиной ошибки. Я лишь могу предположить, что у вас очень много одновременно используется строк, массивов и т.д. Кроме того, если вы используете одновременно все 255 баз данных и для каждой из них выполняете
LOCATE, то все 255 баз данных будут хранить кодовый блок
bFor. Этот ткодовый блок в любой случае создается командой
LOCATE, даже если вы сами не указываете опцию команды
FOR. То есть по умолчанию эта команда его кладет равным следующему кодовому блоку
IF ( ISNIL( bFor ) )
bFor := { || .T. }
ENDIF
Я конечно понимаю, что вам не стало легче от сообщенной мной информации, но тем не менее вы по крайней мере можете считать, что причина ошибки не в самой
__DBSETLOC, а в другом месте вашей программы.