![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Странное выражение: SetLength(S,Length(PChar(S))); [D7, Win95/98, WinXP]
Leaner © (2004-10-18 17:25:00)В некоторых исходниках ( например Jvcl ) встречаю подобную процедуру:
procedure StrResetLength(var S:string;
begin
SetLength(S,Length(PChar(S)));
end;
Интересно почему используют ее, а не, натример,S:=PChar(S); ?
Владислав (2004-10-20 10:06:00) [1]> jack128 © (19.10.04 18:34) [8]
" Владислав © (19.10.04 15:13) [7]
В коде
S:=PChar(S);
произойдет копирование содержимого строки, если исходная строка содержит "значимые" символы.
в коде SetLength(S,Length(PChar(S))); будет тоже самое.."
Если вести разговор об этих двух вариантах, то нижний вариант в многопоточной системе может привести к большей фрагментированности памяти. Больше существенных отличий я не вижу.
А в своем 7 посте я сравнивал вариант DiamondShark © (18.10.04 18:45) [2] и S:=PChar(S).
Leaner (2004-10-19 19:54:00) [2]Всем огромное спасибо.
После того как все разжевали, действительно, стало понятно.
jack128 (2004-10-19 19:43:00) [3]Небольшое дополнение к
DiamondShark © (19.10.04 14:09) [6]
Теперь S:=PChar(S);
Преобразование к PChar
Подсчет длины
Выделение памяти
Копирование
Освобождение старой копии S
Leaner © (19.10.04 19:25) [9]
теперь, я думаю понятно что лудше ;-)
Leaner (2004-10-19 19:25:00) [4]>Выделение памяти,копирование,освобождение старой копии S
>Преобразование к PChar, подсчёт длины, и одно изменение >размера "по месту".
И какой из этих вариантов предпочтительней ?
jack128 (2004-10-19 18:34:00) [5]Владислав © (19.10.04 15:13) [7]
В коде
S:=PChar(S);
произойдет копирование содержимого строки, если исходная строка содержит "значимые" символы.
в коде SetLength(S,Length(PChar(S)));будет тоже самое..
Владислав (2004-10-19 15:13:00) [6]> jack128 © (19.10.04 13:54) [5]
"Или у Вас, Владислав, есть какие нить соображения по этому поводу??"
В коде
S:=PChar(S);
произойдет копирование содержимого строки, если исходная строка содержит "значимые" символы.
DiamondShark (2004-10-19 14:09:00) [7]
> Почему хуже ?
Ну, не хуже.
Как выполняется SetLength(S,Length(PChar(S)))?
PChar(S) возвратит ссылку на содержимое S, или на на заглушку #0 (функция _LStrToPChar)
Для передачи в Length будет создана временная переменная типа string и значение PChar будет преобразовано в string (_LStrFromPChar), для чего будет выделена динамическая память.
SetLength изменит размер строки (вызовом _ReallocMem)
Временная строка будет разрушена.
Итого имеем:
Обращение к менеджеру памяти на выделенеие
Копирование
Обращение к менеджеру памяти на изменение размера (которое происходит "по месту", т.к. новая строка всегда не длиннее исходной)
Обращение к менеджеру памяти на освобождение.
Теперь S:=PChar(S);
Выделение памяти
Копирование
Освобождение старой копии S
Получается, вообще-то, не хуже, даже чуть-чуть лучше.
SetLength(S,StrLen(PChar(S)));
Преобразование к PChar, подсчёт длины, и одно изменение размера "по месту".
jack128 (2004-10-19 13:54:00) [8]Leaner © (19.10.04 13:31) [4]
Leaner © (18.10.04 17:25)
procedure StrResetLength(var S:string;
begin
SetLength(S,Length(PChar(S)));
end;
PChar(s) - вернет @s[1] (обычно) Length(PChar(s)) - будет создана новая строка, в которые будут скопированы первые StrLen(PChar(s)) символов) и вызовется Length(s) для полученной строки. ну и SetLength
Для варианта DS новая длинная строка не будет создоваться, просто строка сканируется до первого нуля и ей(строке) устанавливается новая длина..
> S:=PChar(S);
PChar(s), создание новой строки(как твоем случае), иничтожениестарой строки и присвоение переменной s - новой строки
Что для менеджера тяжелее - освобождение блока памяти или уменьшение его размера - это еще вопрос, так что я бы не утверждал, что
Владислав © (19.10.04 8:23) [3]
это еще хуже, чем в приведенном Вами выше варианте.
Или у Вас, Владислав, есть какие нить соображения по этому поводу??
Leaner (2004-10-19 13:31:00) [9]>Владислав
>Потому, что это еще хуже, чем в приведенном Вами выше варианте.
Почему хуже ?
Владислав (2004-10-19 08:23:00) [10]> Leaner © (18.10.04 17:25)
"Интересно почему используют ее, а не, натример,S:=PChar(S); ?"
Потому, что это еще хуже, чем в приведенном Вами выше варианте.
А лучший вариант см. DiamondShark © (18.10.04 18:45) [2].
А все дело в перераспределении памяти.
DiamondShark (2004-10-18 18:45:00) [11]Плохой код.
Так лучше:
procedure StrResetLength(var S:string);
begin
SetLength(S,StrLen(PChar(S)));
end;
Reindeer Moss Eater (2004-10-18 17:30:00) [12]Видимо сразу после того, как был выделен буфер под нултерминатед строку для API функции.
Что бы обрезать хвост.