Форум: "Основная";
Текущий архив: 2004.10.31;
Скачать: [xml.tar.bz2];
ВнизСтранное выражение: 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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.032 c