首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi:临时PChar是否保证在PChar指向的字符串变量被更改后具有相同的值?

Delphi:临时PChar是否保证在PChar指向的字符串变量被更改后具有相同的值?
EN

Stack Overflow用户
提问于 2012-12-29 06:32:40
回答 2查看 337关注 0票数 6

下面的代码在我的系统中按预期运行,但我不确定P变量MyArray[0]更改为新值后是否保证具有相同的值。

代码语言:javascript
复制
procedure Test;
var
  MyArray: array of string;
  P : PChar;

begin
  SetLength(MyArray, 2);
  MyArray[0] := 'ABCD';
  MyArray[1] := '1234';

  // Is P guaranteed to have the same value all the time?
  P := PChar(MyArray[0]);

  MyArray[0] := MyArray[1];
  MyArray[1] := P;

  WriteLn(MyArray[0]);
  WriteLn(MyArray[1]);
end;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-29 08:09:52

您的代码在技术上无效。它的运行完全是因为一个不应该依赖的实现细节。

让我们看一看代码的相关部分:

代码语言:javascript
复制
P := PChar(MyArray[0]);
MyArray[0] := MyArray[1];
MyArray[1] := P;   

首先,我们指出了MyArray的第一个特征。然后我们分配给MyArray。此时,没有理由使P所指向的字符串缓冲区保持活动。没有字符串变量引用它。它的引用计数已经变为零,因此它应该被取消分配。这使得随后使用的P无效。

在这种情况下,为什么您的代码运行?因为你使用的字符串恰好是文字。因此,它们以等于-1的引用计数存储,并绕过字符串使用的常规堆分配例程。但是,如果要使用非文字的字符串值,那么我在上面一段中所描述的就会变成现实。我希望你真正的代码不使用文字。

所以你的实际问题有点毫无意义。P指针只是指向一个内存块。它一直指向同一内存块,直到修改指针为止。如果您修改内存块的内容,那么如果您取消引用,P将看到这些修改。和任何其他指针一样,它只是一个指针。

您需要小心使用PChar变量。在您的使用中,它是指向编译器托管对象的非托管指针。这为错误提供了很大的空间,而且您已经掉进了陷阱。如果您想要一个字符串的副本,那么将一个副本放入另一个字符串变量中。

票数 13
EN

Stack Overflow用户

发布于 2012-12-29 08:34:38

从字符串到PChar的类型转换似乎与获取其地址不同。参见下面的代码,它将接受字符串的地址。

代码语言:javascript
复制
procedure Test;
var
  MyArray: array of string;
  P : ^String;

begin
  SetLength(MyArray, 2);
  MyArray[0] := 'ABCD';
  MyArray[1] := '1234';

  // take the pointer
  P := @MyArray[0];

  WriteLn(MyArray[0]);
  WriteLn(MyArray[1]);
  WriteLn(P^);

  // when content of array changes, P^ will change as well
  MyArray[0] := 'HELLO';
  WriteLn(P^);
end;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14079321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档