Вниз
Скачать: CL | DM;

работа с 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 вся ветка

Скачать: CL | DM;



Память: 0.49 MB
Время: 0.013 c
1-13225
GenezZ
2003-05-23 04:27
2003.06.05
Сохранение текстового файла..................................


1-13148
lipskiy
2003-05-18 01:25
2003.06.05
Как правильно добавить иконку в ресурсы программы?


1-13160
KIE
2003-05-14 15:41
2003.06.05
Delphi и и Excel


3-13054
Viktor
2003-05-17 05:18
2003.06.05
Перенос приложения на другой компьютер


1-13301
Aleksei85
2003-05-24 22:45
2003.06.05
Почему картинки на кнопке в ToolBar не видно?




   Наверх