Delphi: Console Input + SetLength
Аллоха, All!
А я вот щас как сморожу очередную глупость:
Почему данный код вылетает с Violation-ом после ввода по такому
принципу: следующий введенный набор символов короче чем предыдущий?
Например после ввода такой последовательности:
rrrrrr<enter>
rrr<enter>
rr<enter>
Код выдран из более весомой программы, так что про смысл данных
манипуляций не спрашивайте:
program WinSock_Client;
{$APPTYPE CONSOLE}
uses
Windows;
const cSigExit = 'q';
var TmpBuf: string;
buf: array of byte;
vSize: integer;
begin
repeat
Buf := nil;
Readln(TmpBuf);
vSize := Length(TmpBuf);
SetLength(Buf, vSize); <ошибка вылетает вот здесь
lstrcpy(@Buf, @TmpBuf);
until chr(buf[0]) = cSigExit;
end.
Здравствуйте !
Может, я глубоко заблуждаюсь, но, имхо:
TmpBuf - паскалевская строка (то есть длина хранится в 1-м байте) ?
lstrcpy копирует null-terminated строки (с завершающим нулем), то есть
при копировании из области памяти, указанной @TmpBuf, может производить
чтение за допустимыми границами (тут может и ошибка защиты вылезти).
Т.к. lstrcpy еще и пишет в Buf, длина которого установлена, кстати,
равной длине строки TmpBuf, то тут также может возникнуть ошибка
защиты (уже на запись).
Не знаю что делает SetLength (как работает, точнее), но судя по всему,
т.к. ее назначение - изменить размер выделенного блока памяти (подобно
realloc (сишной), то, надо полагать, при выделении блока памяти, для
блока выделяется размер больше указанного и вначале (например),
блока хранится служебная инфа (о азмере блока, и.т.д.).
Ее (служебную инфу) можно легко перетереть 9возможно этои случается).
Тогда при следующих манипуляциях с этим блоком (попытке удалить,
изменить размер) и будет валиться.
Что можно посоветовать.
Если уж нужно скопировать из паскалевской в null-terminated строку, то
воспользоваться, например, memcpy (т.к. длина строки известна) и еще
выделить Buf на 1 побольше и проставить в конец Buf 0.
--
С уважением, Вахтуров Виктор.
Номер выпуска : 4574
Возраст листа : 625 (дней)
Количество подписчиков : 527
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/380458
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru