Отправляет email-рассылки с помощью сервиса Sendsay

Программирование. Форум !!!

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.

Ответить   Tue, 7 Jun 2005 16:00:13 +0500 (#380145)

 

Ответы:

Здравствуйте !



Может, я глубоко заблуждаюсь, но, имхо:
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

Ответить   Tue, 7 Jun 2005 22:21:18 +0400 (#380458)

 

Хаю ду ю ду Victor V. Vakchturov?

Смотрю и вижу, как ты печатаешь умные вещи и дай-ка, думаю,
тоже что-нибудь напечатаю:

О спасибо! Вместо lstrcpy сделал CopyMemory(Buf, @(TmpBuf[1]), vSize);
Блин совсем забыл про то что у string нулевой индекс низя трогать :)

Ответить   Wed, 8 Jun 2005 09:06:46 +0500 (#380670)

 

String в Delphi не паскалевая строка,а null-terminated string

Номер выпуска : 4581
Возраст листа : 626 (дней)
Количество подписчиков : 527
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/380823
Получить правила : 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

Ответить   "Upiter" Wed, 8 Jun 2005 10:53:43 +0200 (#380823)

 

Хаю ду ю ду Upiter?

Смотрю и вижу, как ты печатаешь умные вещи и дай-ка, думаю,
тоже что-нибудь напечатаю:

Но нулевой индекс все равно зарезервирован.

Ответить   Wed, 8 Jun 2005 19:07:29 +0500 (#381124)

 

Здравствуйте, Александр.

Вы писали 8 июня 2005 г., 20:07:29:

Вообще в Делфи string интерпритируется в зависимости от настроек
компиляции. string как ShortString или как PChar.
Поэтому и есть совместимость array[0..200] char = string[200] и
возможно stringvar:=arrayvar;
А вот сходу присвойть стрингу значение PChar не получится.
Так какой же это тип?

Ответить   Wed, 8 Jun 2005 23:35:05 +0600 (#381193)