Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.044 c
1-1098044705
Closer
2004-10-18 00:25
2004.10.31
Как очистить экран в консольном приложении?


14-1097222400
inic
2004-10-08 12:00
2004.10.31
Кощунственные вещи в жизни происходят :(


14-1097236306
Alone
2004-10-08 15:51
2004.10.31
Компьютер-розетка :)


4-1096021630
Antonmm2
2004-09-24 14:27
2004.10.31
Устройства


1-1097673237
Uran
2004-10-13 17:13
2004.10.31
Цифровые символы в строке





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский