下面的代码在我的系统中按预期运行,但我不确定P变量在MyArray[0]更改为新值后是否保证具有相同的值。
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;发布于 2012-12-29 08:09:52
您的代码在技术上无效。它的运行完全是因为一个不应该依赖的实现细节。
让我们看一看代码的相关部分:
P := PChar(MyArray[0]);
MyArray[0] := MyArray[1];
MyArray[1] := P; 首先,我们指出了MyArray的第一个特征。然后我们分配给MyArray。此时,没有理由使P所指向的字符串缓冲区保持活动。没有字符串变量引用它。它的引用计数已经变为零,因此它应该被取消分配。这使得随后使用的P无效。
在这种情况下,为什么您的代码运行?因为你使用的字符串恰好是文字。因此,它们以等于-1的引用计数存储,并绕过字符串使用的常规堆分配例程。但是,如果要使用非文字的字符串值,那么我在上面一段中所描述的就会变成现实。我希望你真正的代码不使用文字。
所以你的实际问题有点毫无意义。P指针只是指向一个内存块。它一直指向同一内存块,直到修改指针为止。如果您修改内存块的内容,那么如果您取消引用,P将看到这些修改。和任何其他指针一样,它只是一个指针。
您需要小心使用PChar变量。在您的使用中,它是指向编译器托管对象的非托管指针。这为错误提供了很大的空间,而且您已经掉进了陷阱。如果您想要一个字符串的副本,那么将一个副本放入另一个字符串变量中。
发布于 2012-12-29 08:34:38
从字符串到PChar的类型转换似乎与获取其地址不同。参见下面的代码,它将接受字符串的地址。
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;https://stackoverflow.com/questions/14079321
复制相似问题