Форум: "Основная";
Текущий архив: 2003.05.15;
Скачать: [xml.tar.bz2];
ВнизКуда деваются символы? Найти похожие ветки
← →
Serg! (2003-05-03 19:04) [0]Уважаемые мастера, у меня к вам небольшой вопросик. Вот например
...
var
s1: string;
s2: string[5];
...
begin
s1:="more_then_5_chars";
s2:=s1; //куда деваются остальные символы????
← →
Плохой человек (2003-05-03 19:06) [1]Обрезаются.
← →
Morfein (2003-05-03 19:12) [2]В строке s2:=s1; происходит копирование только 5-ти байт, поскольку типа ShortString не есть тип с динамически перераспределяемой памятью...
← →
Serg! (2003-05-03 19:15) [3]А я слышал, что "обрезанные" символы помещаются куда-то в память...
← →
Morfein (2003-05-03 19:21) [4]Если бы они помещались куда-то в память, то возврат из первой же функции, в случае вызова вышеуказанного кода в функции, привёл бы к краху программы, потому как произошло бы перетирание адресов возврата в стэке(а локальные переменные процедур там и хранятся)... А перетирание должно было бы произойти потому, что тип ShortString не есть динамический(!), и менеджер памяти не может указать куда-то переместить "лишние" байты...
← →
default (2003-05-03 19:36) [5]program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
S1: String[5];
S2: String;
begin
// вот так по дефолту
S1 := "12345678";
WriteLn(S1);
// а вот так можно обмануть компилятор!
S2 := #8"12345678";
Move(S2[1], S1, 9);
WriteLn(S1); // на экране будет строка: "12345678"
ReadLn
end.
← →
Anatoly Podgoretsky (2003-05-03 19:38) [6]Serg! (03.05.03 19:15)
Правильно мыслишь, они в 3D ассоциативной памяти
← →
Serg! (2003-05-03 19:40) [7]> default
А что значит #8 ???
← →
Serg! (2003-05-03 19:43) [8]Anatoly Podgoretsky © (03.05.03 19:38)
Что это значит?
← →
Anatoly Podgoretsky (2003-05-03 19:45) [9]Неважно, важно другое, что здесь попорчена чужая память.
← →
Serg! (2003-05-03 19:52) [10]Anatoly Podgoretsky © (03.05.03 19:45)
То есть память, которая используется чужой прогой?
← →
default (2003-05-03 19:59) [11]скорее всего тут ничего не портится
вот если мы попытаемя копировать больше 256 байт - то тут возможно...на практике пусть кто-нибудь попробует кому не лень
to Serg!
#8 - это длина строки
для типа ShortInt в первом байте строки содержится её длина - этим автоматом и накладывается ограничение на длину таких строк -255 символов
← →
Юрий Зотов (2003-05-03 20:00) [12]> default © (03.05.03 19:36)
Наверное, так действительно можно обмануть компилятор (особенно, при отключенном range checking). Но если сразу за строкой S1 в памяти находилось что-то нужное, то Вы обманете сами себя. Успешным затиранием этого нужного. И с любыми непредсказуемыми последствиями.
Кстати, символ #8 здесь совершенно ни при чем (можете его убрать и ничего не изменится). Это всего лишь символ ЗАБОЙ (Backspace) и от других ASCII-символов он ничем не отличается (разве что при выводе на консоль может эмулировать нажатие соответствующей клавиши - в DOS это точно, а под Windows я не проверял, но возможно). Вся фишка Вашего кода состоит не в #8, а в том, что Move тупо копирует содержимое памяти без всяких проверок. А уж кого Вы при этом обманете, себя или компилятор - это ее не интересует.
← →
Anatoly Podgoretsky (2003-05-03 20:03) [13]Serg! (03.05.03 19:52)
Нет своей программы, памяти не принадлежащей S1, ее размер 6 байт, а ты туда гоним 9
← →
Юрий Зотов (2003-05-03 20:04) [14]Не посмотрел внимательно. Насчет #8 - в данном случае это и правда длина строки. Но остальное верно - 3 байта после строки S1 Вы затираете намертво и с любыми непредсказуемыми последствиями.
← →
default (2003-05-03 20:30) [15]to Юрий Зотов
"Наверное, так действительно можно обмануть компилятор (особенно, при отключенном range checking).
Но если сразу за строкой S1 в памяти находилось что-то нужное, то Вы обманете сами себя.
Успешным затиранием этого нужного. И с любыми непредсказуемыми последствиями."
Это я прекрасно понимаю, Юрий
Это просто как вариант - кому-то будет интересным наверно - мне бы было интересно
если бы я такое увидел - захотелось бы понять "фишку"
"Кстати, символ #8 здесь совершенно ни при чем (можете его убрать и ничего не изменится).
Это всего лишь символ ЗАБОЙ (Backspace) и от других ASCII-символов он ничем не отличается
(разве что при выводе на консоль может эмулировать нажатие соответствующей клавиши - в DOS
это точно, а под Windows я не проверял, но возможно)."
у меня другой результат:
если делать
S2 := "12345678";
Move(S2[1], S1, 8);
после этого S1[0] = "1" - как и должно быть!
но на консоль выводится "2345678" и ещё какой-то левый символ(так как Byte(S1[0]) = 49)
но делаем "отчистку" типа S1 := S1 и выведется "23456"(теперь Byte(S1[0]) = 5)
всё вроде по правилам...
"Вся фишка Вашего кода состоит не в #8,
а в том, что Move тупо копирует содержимое памяти без всяких проверок. А уж кого Вы при этом
обманете, себя или компилятор - это ее не интересует."
Поэтому её и применял!
P.S.
Кстати на счёт задачи что Вы мне дали помните(сделать TButton нестандартного цвета)?
Вы её практически решали ?А то всё сводится к тому что всё ручками надо рисовать...
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.05.15;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.007 c