Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.31;
Скачать: CL | DM;

Вниз

Странное выражение: SetLength(S,Length(PChar(S)));   Найти похожие ветки 

 
Leaner ©   (2004-10-18 17:25) [0]

В некоторых исходниках ( например Jvcl ) встречаю подобную процедуру:
procedure StrResetLength(var S:string;
begin
SetLength(S,Length(PChar(S)));
end;

Интересно почему используют ее, а не, натример,S:=PChar(S); ?


 
Reindeer Moss Eater ©   (2004-10-18 17:30) [1]

Видимо сразу после того, как был выделен буфер под нултерминатед строку для API функции.
Что бы обрезать хвост.


 
DiamondShark ©   (2004-10-18 18:45) [2]

Плохой код.

Так лучше:

procedure StrResetLength(var S:string);
begin
SetLength(S,StrLen(PChar(S)));
end;


 
Владислав ©   (2004-10-19 08:23) [3]

> Leaner ©   (18.10.04 17:25)  

"Интересно почему используют ее, а не, натример,S:=PChar(S); ?"

Потому, что это еще хуже, чем в приведенном Вами выше варианте.
А лучший вариант см. DiamondShark ©   (18.10.04 18:45) [2].

А все дело в перераспределении памяти.


 
Leaner ©   (2004-10-19 13:31) [4]

>Владислав
>Потому, что это еще хуже, чем в приведенном Вами выше варианте.
Почему хуже ?


 
jack128 ©   (2004-10-19 13:54) [5]

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]
это еще хуже, чем в приведенном Вами выше варианте.


Или у Вас, Владислав, есть какие нить соображения по этому поводу??


 
DiamondShark ©   (2004-10-19 14:09) [6]


> Почему хуже ?

Ну, не хуже.

Как выполняется 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, подсчёт длины, и одно изменение размера "по месту".


 
Владислав ©   (2004-10-19 15:13) [7]

> jack128 ©   (19.10.04 13:54) [5]

"Или у Вас, Владислав, есть какие нить соображения по этому поводу??"

В коде
S:=PChar(S);
произойдет копирование содержимого строки, если исходная строка содержит "значимые" символы.


 
jack128 ©   (2004-10-19 18:34) [8]

Владислав ©   (19.10.04 15:13) [7]
В коде
S:=PChar(S);
произойдет копирование содержимого строки, если исходная строка содержит "значимые" символы.


в коде SetLength(S,Length(PChar(S))); будет тоже самое..


 
Leaner ©   (2004-10-19 19:25) [9]

>Выделение памяти,копирование,освобождение старой копии S
>Преобразование к PChar, подсчёт длины, и одно изменение >размера "по месту".
И какой из этих вариантов предпочтительней ?


 
jack128 ©   (2004-10-19 19:43) [10]

Небольшое дополнение к
DiamondShark ©   (19.10.04 14:09) [6]
Теперь S:=PChar(S);

Преобразование к PChar
Подсчет длины

Выделение памяти
Копирование
Освобождение старой копии S

Leaner ©   (19.10.04 19:25) [9]
теперь, я думаю понятно что лудше ;-)


 
Leaner ©   (2004-10-19 19:54) [11]

Всем огромное спасибо.
После того как все разжевали, действительно, стало понятно.


 
Владислав ©   (2004-10-20 10:06) [12]

> 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).



Страницы: 1 вся ветка

Текущий архив: 2004.10.31;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.026 c
14-1097469635
Layner
2004-10-11 08:40
2004.10.31
SP2 на XP, последствия...


4-1095573471
Bil Bal Dur
2004-09-19 09:57
2004.10.31
Работа с LPT портом в XP


1-1097843033
Саша
2004-10-15 16:23
2004.10.31
Разрыв слитной строки в DrawText


1-1098166414
SergP.
2004-10-19 10:13
2004.10.31
2 отчета в QuickReport


14-1097561753
SPeller
2004-10-12 10:15
2004.10.31
Удалять или не удалять? Вот в чем вопрос