Зачем подпрограмме, чтобы PChar (приведение типа из строки) передавался ей, оставался в памяти после возвращения? - PullRequest
2 голосов
/ 08 февраля 2012
var
  S: string;
begin
  SetLength(S, MAX_SIZE);// when casting to a PChar, be sure the string is not empty
  SetLength(S, GetModuleFilename(0, PChar(S), Length(S)));
  // statements
end;

Чтобы исключить издержки копирования буфера, вы можете привести строку к PChar (если вы уверены, что подпрограмме не нужен PChar, чтобы оставаться в памяти). http://docwiki.embarcadero.com/RADStudio/en/Passing_a_Local_Variable_as_a_PChar

У нас есть строка, и она будет оставаться в памяти до тех пор, пока счетчик ссылок не уменьшится до 0, поэтому она не будет удалена в ходе области видимости. Итак, почему нам нужно PChar, чтобы остаться в памяти? Существует ли какая-либо функция API, для которой требуется точно такая же ссылка PChar, которая была ранее передана другой функции API?

Особенно я рассматриваю пример кода. Итак, вопрос должен звучать так: «Почему подпрограмме нужен PChar (приведенный к типу из строки), который будет передан ей, и останется в памяти после ее возвращения?». Асинхронные процедуры ввода-вывода или асинхронный метод, которые обращаются к переданному pchar после возврата вызывающей стороны, или изменение глобальной строки другим потоком - веские причины.

1 Ответ

6 голосов
/ 08 февраля 2012

Иногда API сохраняет указатель до более позднего времени.Например, подумайте об асинхронном вводе-выводе.

Или, если вы написали код, подобный следующему, он тоже потерпит неудачу:

function Broken():PChar;
var s:string;
begin
  s:=IntToStr(Random(100));//no string constant
  return PChar(s);
end;

Один важный момент - если вы приведете строку с refcount> 1на PChar, он создаст копию, а затем передаст вам строку с refcount = 1.Таким образом, ваш PChar становится недействительным, как только введенные вами значения становятся недействительными, даже если у него был refcount> 1.

Еще один неработающий пример:

var p:PChar;
var s:string;

s := IntToStr(Random(100));//no string constant
p := PChar(s);
s := "ABC";
DoSomething(p);//p is invalid by now
...