Запрос Delphi — ADO и FillChar генерируют ошибки

#string #delphi #delphi-7 #tadoquery

#строка #delphi #delphi-7 #tadoquery

Вопрос:

У меня есть следующий код:

 var wqry:TAdoQuery;
...
  FillChar(wSpaces,cSpacesAfter,' ');
  try
    wqry := TADOQuery.Create(nil);//here the error
    wqry.Connection:=...
  

cSpacesAfter является константой и имеет значение 1035. wSpaces — это локальная строковая переменная. Проблема в том, что я получаю следующую ошибку при создании TADOQuery

введите описание изображения здесь

даже если это на французском, я полагаю, вы уловили идею…..

Если я прокомментирую код FillChar, все работает нормально. У меня обычные директивы компилятора, ничего особенного. Я использую Delphi 7.

Кто-нибудь может сказать мне, что не так с этим кодом?

Комментарии:

1. Если это скопированный код, вы инициализируете, wqry но используете wry . Обратите внимание на отсутствие q во втором имени. Если это не скопированный код, пожалуйста, исправьте это (скопировав вставленный код)

2. wSpaces:=stringofchar(‘ ‘,cSpacesAfter); — устранена проблема. ошибка не возникает.

3. спасибо за -1. действительно, это был глупый вопрос, недостаток сна сделал свое дело.

Ответ №1:

Проблемный код, скорее всего, этот

 FillChar(wSpaces,cSpacesAfter,' ');
  

Я предполагаю, что wSpaces имеет строковый тип. Строковая переменная на самом деле является не чем иным, как указателем на структуру данных, которая содержит строку. Вам не нужно использовать синтаксис указателя, потому что компилятор позаботится об этом за вас.

Итак, что делает этот код, это перезаписывает переменную, содержащую этот указатель, 4 символами пробела, а затем записывает еще 1031 пробел поверх всего, что следует за переменной. Короче говоря, вы полностью повредите свою память. Это могло бы объяснить, почему FillChar работает, но уже следующая строка кода умирает мучительной и драматичной смертью.

Если в вашей строке действительно было место для 1035 символов, вы могли бы вместо этого написать:

 FillChar(wSpaces[1], cSpacesAfter, ' ');
  

Однако, если можно написать более идиоматично:

 wSpaces := StringOfChar(' ', cSpacesAfter);
  

Комментарии:

1. да, wSpaces является локальной строковой переменной. FillChar(wSpaces[1], cSpacesAfter, ‘ ‘); — генерирует 000000.. AV.

2. @RBA Он генерирует AV только в том случае, если вы сначала не выделите некоторое хранилище! В любом случае, StringOfChar — это ваш ответ, как вы сказали в комментарии выше.

Ответ №2:

Процедура FillChar заполняет раздел буфера хранилища одним и тем же байтом или символом FillValue, количество заполнений раз.

В основном используется для инициализации массивов чисел. Его можно использовать для инициализации записей и строк, но следует соблюдать осторожность, чтобы избежать перезаписи полей длины. StringOfChar лучше всего подходит для заполнения строк одним и тем же символом.

Вы уверены, что размер wSpaces достаточен для размещения всех CSPACES после того, как вы в него напишете?

Комментарии:

1. если добавлена setlength(wSpaces,cSpacesAfter 1); перед функцией FillChar, ошибка все равно генерируется.

2. Вам пришлось бы сделать что-то вроде этого: Setlength(wSpaces, cSpacesAfter); FillChar(wSpaces[1], cSpacesAfter, ' '); согласно моему ответу, но StringOfChar намного лучше.