Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Странное выражение: 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 функции.
Что бы обрезать хвост.


Наверх

Титульная страница Поиск, карта сайта Написать письмо