Вверх ↑
Этот топик читают: Гость
Ответов: 4622
Рейтинг: 746
#16: 2015-03-30 11:47:24 ЛС | профиль | цитата
nesco писал(а):
как это отобразится на исходной строке?
Так я тебе предложил удостовериться, что никак.

Add(Button,10504036,217,203)
{
Left=150
Top=120
link(onClick,11970995:doWork,[])
}
Add(InlineCode,11970995,301,203)
{
WorkPoints=#6:doWork|
EventPoints=#8:onResult|
VarPoints=#4:Var1|4:Var2|
DataPoints=#5:Data1|5:Data2|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|21:uses kol,Share,Debug;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|28: Data1, Data2:THI_Event;|27: onResult:THI_Event; |51: procedure doWork(var _Data:TData; index:word);|49: procedure Var1(var _Data:TData; index:word);|49: procedure Var2(var _Data:TData; index:word);|5: end;|0:|14:implementation|0:|0:|0:|58:procedure THiAsmClass.doWork(var _Data:TData; index:word);|3:var|18: s1, s2: string; |5:begin|37: s1 := ReadString(_Data, Data1, '');|11: s2 := s1;|19: SetLength(s2, 0);|13: _debug(s1);|2: |33: // ReadInteger(_Data, Data2, 0)|42: // _hi_CreateEvent(_Data, @onResult, 0);|33: //_hi_OnEvent(onResult, 'abc');|4:end;|0:|0:|57:procedure THiAsmClass.Var1(var _Data:TData; index:word); |5:begin|22: dtInteger(_Data, 0);|4:end;|0:|57:procedure THiAsmClass.Var2(var _Data:TData; index:word); |5:begin|22: dtString(_Data, '');|4:end;|0:|4:end.|
link(Data1,12710020:Text,[])
}
Add(Edit,12710020,301,147)
{
Left=75
Top=50
Width=80
}
В s1 - исходная строка, которая не должна измениться.
Присваиваем её переменной s2. По твоей логике эти две переменные ссылаются на одну и ту же строку. Вроде это так и есть.
И по этой же логике изменение размера s2 (или любого символа в s2) должно вызвать те же изменения в s1. Но не вызывает по описанной выше причине: перед внесением любых изменений в s2, исходная строка копируется и s2 уже указывает на другую строку, чем s1.

Со StrCase не проверял, но там произойдет то же самое.
ПРОВЕРИЛ:

Add(Button,1278441,196,462)
{
Left=75
Top=140
link(onClick,13115854:doEvent1,[])
}
Add(Memory,7470773,245,343)
{
Default=String(abcdef)
}
Add(Hub,13115854,252,462)
{
OutCount=3
link(onEvent1,1958132:doMessage,[])
link(onEvent2,13269969:doModify,[(308,475)(308,552)])
link(onEvent3,300142:doMessage,[(287,482)(287,643)])
}
Add(LineBreakEx,2624889,350,427)
{
Caption="str"
Type=2
}
Add(LineBreakEx,6354434,245,385)
{
Caption="str"
Type=3
link(_Data,7470773:Value,[])
}
Add(Message,1958132,350,462)
{
Caption="Before"
link(Message,2624889:getVar,[])
}
Add(StrCase,13269969,350,546)
{
Type=1
link(onModify,7657121:doText,[])
link(Str,5777113:getVar,[])
}
Add(LineBreakEx,5777113,350,518)
{
Caption="str"
Type=2
}
Add(LineBreakEx,9602436,350,602)
{
Caption="str"
Type=2
}
Add(Message,300142,350,637)
{
Caption="Before"
link(Message,9602436:getVar,[])
}
Add(Label,7657121,413,546)
{
Left=140
Top=145
}
В коде убрал ту порнографию с копированием, разницы не заметил.

Разница будет, когда одна и та же переменная используется в разных местах. Например, у нас упомянутая тобой TData между компонентами передается как var параметр. То-есть, разные компоненты получают именно одну и ту же переменную. Тогда если изменить поле TData.sdata, это изменение увидят все компоненты. Например, в хабе как раз происходит принудительное копирование TData, так как в одном событии какой нибудь компонент может изменить её содержимое (_hi_CreateEvent), тогда остальные события выдадут уже измененное значение.
карма: 26

0
Разработчик
Ответов: 26072
Рейтинг: 2122
#17: 2015-03-30 12:08:51 ЛС | профиль | цитата
Netspirit, тогда объясни, почему у Rysik-а с кодом Tad-a выдает мусор на выходе
карма: 22

0
Ответов: 4622
Рейтинг: 746
#18: 2015-03-30 12:25:55 ЛС | профиль | цитата
Так уже ж объяснили: если длина строки увеличивается, то новая часть неинициализирована, то-есть мусор от предыдущих операций.

карма: 26

0
Разработчик
Ответов: 26072
Рейтинг: 2122
#19: 2015-03-30 12:32:00 ЛС | профиль | цитата
Netspirit писал(а):
Так уже ж объяснили: если длина строки увеличивается, то новая часть неинициализирована, то-есть мусор от предыдущих операций.

Кажется, я понял. Я добавил в конец #0. Вывод на экран получился по нультерминатной строке, а не по длине, вот мусора и не было.
карма: 22

0
Ответов: 16884
Рейтинг: 1239
#20: 2015-03-30 12:33:11 ЛС | профиль | цитата
nesco писал(а):
Попробуй убрать #0 и использовать исходную строку дальше

Убрал

#pas
procedure THIStrCase._work_doModify;
var
str: string;
begin
str := ReadString(_Data, _data_Str); //+#0;
_prop_Type(str);
// SetLength(str, length(str) - 1);
_hi_CreateEvent(_Data, @_event_onModify, str);
end;
Режим Upper
Исходная "пробная программа"
Результат "ПРОБНАЯ ПРОГРАММА"
Исходная "пробная программа"

ну и что ? Прикол то в чем ?
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
файлы: 1v_prikol.png [23.4KB] [691]
Разработчик
Ответов: 26072
Рейтинг: 2122
#21: 2015-03-30 12:35:28 ЛС | профиль | цитата
Tad писал(а):
Прикол то в чем ?

Я уже сейчас не помню точно, давно это было. Но попадалась ситуация, когда преобразование влияло на исходную строку и дальше перла вместо исходной преобразованная строка
карма: 22

0
Ответов: 4622
Рейтинг: 746
#22: 2015-03-30 12:36:32 ЛС | профиль | цитата
Tad, прикол в том, что nesco и остальные, кто не знал, узнали что-то новое и довольно важное для понимания работы строк в Delphi.
nesco писал(а):
преобразование влияло
Я чуть выше объяснил, в каких случаях оно влияет.
карма: 26

0
Ответов: 16884
Рейтинг: 1239
#23: 2015-03-30 12:45:58 ЛС | профиль | цитата
Вот и я о том же.

карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 8889
Рейтинг: 823
#24: 2015-03-30 13:34:50 ЛС | профиль | цитата
Netspirit писал(а):
..понимания работы строк в Delphi..
Да и не только строк. При создании любой переменной выделенная под неё память не чистится
карма: 19

0
Ответов: 16884
Рейтинг: 1239
#25: 2015-03-30 14:03:26 ЛС | профиль | цитата
Леонид писал(а):
При создании любой переменной выделенная под неё память не чистится
Кроме String.
При создании строки память выделяется автоматически; как только на строку не останется ни одной ссылки, память возвращается системе.

------------ Дoбавленo в 14.03:
Леонид, сначала ответил, а только потом понял о чем речь
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 9906
Рейтинг: 351
#26: 2015-03-30 20:02:50 ЛС | профиль | цитата
Мои пять копеек.....

nesco писал(а):
Я уже сейчас не помню точно, давно это было. Но попадалась ситуация, когда преобразование влияло на исходную строку и дальше перла вместо исходной преобразованная строка
А я помню.
Когда пытаешься использовать WinApi (например, для UpperCase), давая ему Pchar(Str), и которое понятия не имеет про Copy-On-Write.
WinApi работает абсолютно правильно, в отличие от встроенных в Дельфи. Зато Дельфячие все знают про Copy-On-Write.

Про количество аллокаций памяти.
При работе со строками - Дельфи не так уж и туп. Он новую память выделяет "с запасом". Причем, мультипликативно, например: в два раза больше (во сколько раз конкретно - не помню). И поэтому, время на аллокацию растет логарифмически (а не линейно!) от количества прибавлений.

Tad писал(а):
При создании строки память выделяется автоматически; как только на строку не останется ни одной ссылки, память возвращается системе.
Добавлю: и ЕЩЕ "память возвращается системе", ЕСЛИ длина этой строки становится нулевой, не важно по какой причине. Строка сразу же становится nil.
Впрочем, и выделяется память не совсем сразу "при создании". Сразу при создании она категорически равна тому же nil. А вот как только длина ее ставится больше 0 -- так сразу и выделяется...

карма: 9

1
Голосовали:Netspirit
Ответов: 16884
Рейтинг: 1239
#27: 2015-03-31 06:31:31 ЛС | профиль | цитата
Архив с окончательным вариантом компонента ( ) в первом посте
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 8889
Рейтинг: 823
#28: 2015-03-31 10:03:23 ЛС | профиль | цитата
Tad, мой загрузчик (Orbit) переволновался и спрашивает: "Уже загружен 2 (два) раза, загрузить ещё раз?", пришлось чистить
Нервотрёпка.jpg
карма: 19

0
файлы: 1Нервотрёпка.jpg [31KB] [529]
Ответов: 4622
Рейтинг: 746
#29: 2015-03-31 10:51:16 ЛС | профиль | цитата
Galkov писал(а):
А я помню.
Когда пытаешься использовать WinApi
Ага, действительно: code_35423.txt
Не подскажешь, в наших компонентах когда следует обращать на это внимание? То-есть, когда изменение строки, полученной по ReadString недопустимо (в каких случаях одна и та же TData используется в нескольких компонентах)?
Предполагаю, во всех случаях, где полученная из других компонентов строка изменяется "на стороне" (Windows API, сторонние dll) нужно делать копию строки.
карма: 26

0
файлы: 1code_35423.txt [1012B] [524]
Ответов: 5227
Рейтинг: 587
#30: 2015-03-31 11:49:51 ЛС | профиль | цитата
Tad, добавь функционалу (типа лево - право)
вот готовое
#pas
function LeftPad(S: string; Ch: Char; Len: Integer): string;
var
RestLen: Integer;
begin
Result := S;
RestLen := Len - Length(s);
if RestLen < 1 then Exit;
Result := S + StringOfChar(Ch, RestLen);
end;

function RightPad(S: string; Ch: Char; Len: Integer): string;
var
RestLen: Integer;
begin
Result := S;
RestLen := Len - Length(s);
if RestLen < 1 then Exit;
Result := StringOfChar(Ch, RestLen) + S;
end;
карма: 4
Мой форум - http://hiasm.bbtalk.me/ схемы, компоненты...
0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)