gpt4 book ai didi

string - 当字符串没有自动触发时如何触发 COW

转载 作者:行者123 更新时间:2023-12-03 15:42:08 25 4
gpt4 key购买 nike

我有一条记录,see this question了解背景信息。

TDigits = AnsiString;  //Should be `= array of NativeUInt`, but string has COW

TBigint = record
Digit: TDigits; // Unsigned number, LSB stored in D[0], MSB in D[size-1]
Size: Byte; // Mininum = 4, maximum 127.
MSI: Byte; // Most significant (native)integer minimum=1, maximum=127
Sign: Shortint;
class operator Implicit(a: Integer): TBigint;

背景
我正在使用一个 bignum 类,它(几乎)像普通整数一样工作。
因此 a:= 1000000*10000000*12000000*10000000*1000000; 会产生非常有用的结果。为此,我使用带有类运算符的记录。这些会触发自动类型转换和初始化。
除非没有转换,因为我将一个 TBigint 分配给另一个 TBigint

解决方案
使用 Ansistring 来存储核心数据,它具有写时复制功能,并且会在需要时克隆自身。

问题:(如果 Delphi 不知道您正在更改字符串,COW 将不起作用)
我有一些纯汇编程序例程,可以操纵伪装成 Ansistring 的数字动态数组

但是当我做这样的事情时:

Label1.Caption:= BigintToStr(b);
..... this fires:

function BigintToStr(const X: TBigint): AnsiString;
var
..
LocX:= x; <<-- assignment, locX and X are joined at the hip.
repeat
D := DivBigint(LocX, 1000000000, LocX); <<-- this routine changes LocX
^^+-- but assembler routines bypass COW

XLocX 位于髋部,无论其中一个发生什么,另一个也会发生。
显然,Delphi 不知道 asm 例程 DivBigint 正在更改 LocX,因此 COW 是正常的。

解决方法
如果我将例程更改为:

function BigintToStr(const X: TBigint): AnsiString;
var
..
LocX:= x;
LocX.Digit[2]:= #0; <<-- inconsequential change to force COW.
repeat
D := DivBigint(LocX, 1000000000, LocX);

Delphi 一切都搞清楚了并且表现得很好。LocXX 已取消链接,一切正常。
但是,我不想在一些空白区域中进行愚蠢的更改。

是否有一种体面/适当/官方*的方法来强制在字符串中触发 COW?
也许是系统调用之类的东西?

*圈出您最喜欢的选项(用手绘圆圈)

最佳答案

应该是评论,但需要更多空间...

如果您需要调用UniqueString或等效函数。
您不妨保留动态记录。

手册中的引用:

Following a call to SetLength, S is guaranteed to reference a unique string or array -- that is, a string or array with a reference count of one. If there is not enough memory available to reallocate the variable, SetLength raises an EOutOfMemory exception.

请注意,此行为甚至在调用 SetLength(Length(myArray)); 时也适用。
Delphi 将为您制作一份副本并解决问题。

事实证明,AnsiStrings 并不需要复杂化,只要您在每个接受记录作为 var 参数的方法中调用 SetLength 即可。

优点
这样做的另一个好处是,如果您调用 SetLength 来扩展数组(经常发生),则添加的空间将被初始化为零。 AnsiString 不会发生任何事情。

此外,无需担心大小转换,因为您的 TXYZ 数组 已经知道其元素的大小。使用 AnsiString 时,您需要在各处添加 * SizeOf(somestruct)

无需类型转换,简化代码;并且在调试器中数据按照设计显示。

A mere call to SetLength makes the dynamic array COW

如您所见,这两个实例不再链接。

关于string - 当字符串没有自动触发时如何触发 COW,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18933146/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com