Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.06.05;
Скачать: [xml.tar.bz2];

Вниз

работа с PChar   Найти похожие ветки 

 
Q   (2003-05-22 17:15) [0]

в справке Дельфи имеется:

A common error when working with PChars is to store in a data structure, or return as a value, a local variable. When your routine ends, the PChar will disappear because it is simply a pointer to memory, and is not a reference counted copy of the string. For example:

function title(n: Integer): PChar;

var
s: string;
begin
s := Format("title - %d", [n]);
Result := PChar(s); // DON"T DO THIS
end;

This example returns a pointer to string data that is freed when the title function returns.

Почему DON"T DO THIS если код работает?
Провел эксперимент. В DLL запихнул ф-ию

function Func1: PChar;
var
s: string;
begin
s := "aaa";
Result := PChar(s);
end;

В программе загружаю DLL и вызываю ф-ию Func1
...
ShowMessage(Func1);
...
прочие манипуляции с рез-том Func1
...
все прекрасно работает.

Где собака порылась? Почему DON"T DO THIS?


 
Юрий Федоров   (2003-05-22 17:18) [1]

Потому что "aaa" - константа, память по нее выделена и не освободится при выходе из процедуры Func1, а присвоение ее строке сводится к присвоению указателя
Попробуй для сравнения так :
function Func1: PChar;
var
s: string;
begin
s := "a" + "a" + "a";
Result := PChar(s);
end;


 
Q   (2003-05-22 17:24) [2]

function Func1: PChar;
var
s: string;
begin
s := "a" + "a" + "a";
Result := PChar(s);
end;

тоже работает, и даже

function Func1(s: string): PChar;
var
s: string;
begin
s := s + "a" + "a" + "a";
Result := PChar(s);
end;

работает. А вот function Func1(var s: string): PChar;
действительно дает ошибку.

Спасибо за разъяснение


 
Q   (2003-05-22 17:31) [3]

Кстати, пример в справке Дельфи работает. Видимо неудачный пример.


 
Юрий Федоров   (2003-05-22 17:46) [4]

Вот такой код :
var SL : TStringList;
i : integer;
begin
SL:=TStringList.Create;
for i:=0 to 10 do
SL.Free;
end;

тоже работает (не валится). И что из того?


 
VMcL   (2003-05-22 17:54) [5]

>Юрий Федоров © (22.05.03 17:46)

Этот код принципиально и не должен валиться.


 
Serginio   (2003-05-22 17:56) [6]

>>> Q (22.05.03 17:24)
Такой код действительно будет работать до тех пор пока память занятая под S не заполниться другими данными, так как S уже не существует занятая ею память заполняется другими данными.


 
Dimka Maslov   (2003-05-22 18:21) [7]

Фактически, при освобождении памяти после строки менеджер динамической памяти Delphi помечает у себя, что данный блок памяти свободен, очистки памяти или изменения аттрибутов доступа к блоку не производится. Следовательно, полученный из функции указатель будет ссылаться на строку, но только до тех пор, пока этот же блок памяти не будет занят при последующем выделении памяти.


 
Юрий Федоров   (2003-05-22 18:22) [8]

VMcL © (22.05.03 17:54)
Это почему же ?


 
VMcL   (2003-05-22 18:30) [9]

>Юрий Федоров © (22.05.03 18:22)

Sorry, неправ. Сдуру перепутал с FreeAndNil :((

Наоборот, он всегда должен вызывать исключение.


 
Romkin   (2003-05-22 18:58) [10]

Не всегда. Память помечается как свободная, пока ее ничто не заполнило - исключения может не быть


 
Anatoly Podgoretsky   (2003-05-22 20:31) [11]

VMcL © (22.05.03 18:30)
Опять вопрос - Это почему же ?
Ответ - как повезет.


 
VMcL   (2003-05-23 00:56) [12]

>Anatoly Podgoretsky © (22.05.03 20:31)
Повезет? В общем-то, да. Я забыл, что менеджер памяти Delphi не сразу отдаёт память системе, поэтому AV может и не возникнуть.


 
Спрашивающий   (2003-05-23 01:59) [13]

Тип PChar является указателем на строку. В отличии от типа String
память автоматически под PChar не выделяется и не высвобождается.
ЗАМЕЧАЕТЕ НЮАНС. Так вот меня честно удивляет тот факт что и в исходниках Делфи и здесь на форуме(практически в каждой ветке на данную тему) приведение осуществляют таким образом P:=PChar(S). Зачем тогда вся эта теория о которой написано в умных книжках кстати о которых Вы уважаемые мастера не забываете упомянуть в ответах с начинающими да еще с некоторой издевкой, а сами приводите код явно не клеющийся с теоритическими основами.
Модератора прошу не удалять данный коментарий.


 
Нуу   (2003-05-23 03:10) [14]

2 Спрашивающий (23.05.03 01:59)
А ты когда-нибудь и где-нибудь в исходниках Делфи встречал выделение или освобождение памяти для строки через приведение типа PChar(s)?
А вот передача параметра в какую-либо функцию через приведение типа - вполне нормальная вещь.


 
Спрашивающий   (2003-05-23 03:46) [15]

А я об этом и говорю что не встречал. Поэтому и коментарий такой теория с практикой в разные стороны разъезжается. Есть предположение что все на себя берет компилятор но это мое предположение.


 
Набережных С.   (2003-05-23 18:48) [16]

>Спрашивающий (23.05.03 01:59)

Молодой человек, Вы явно где-то зашли за угол(выражение из моей молодости) и упорно там стоите. Никаких проблем, кроме созданных самим программистом, конструкция PChar(s) вызвать не может. Компилятор прекрасно осведомлен об особенностях типов PChar и string и практически всегда правильно истолковывает такую конструкцию. Если же у Вас есть конкретные примеры некорректного преобразования, то убедительно прошу привести их для публичного обсуждения. Если же нет, то очень прошу заткнуться - глупости очень быстро утомляют.



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

Форум: "Основная";
Текущий архив: 2003.06.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.011 c
7-13493
Игорь_Г
2003-03-27 01:15
2003.06.05
Работа с драйверами


14-13452
ghg
2003-05-20 07:57
2003.06.05
алгоритмы интерполяции


4-13524
pok
2003-04-07 11:20
2003.06.05
Где то видел но не знаю точно где -- блокировка под Win2k...


1-13171
Новенький
2003-05-26 11:35
2003.06.05
TActionPopupMenuBar


1-13290
Maxim Pshevlotsky
2003-05-24 12:44
2003.06.05
Ошибка при обращении к DCOM обьекту





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский