String 从字节数组创建字符串
我正在尝试使用下面代码中的String 从字节数组创建字符串,string,delphi,stack,dynamic-arrays,delphi-xe4,String,Delphi,Stack,Dynamic Arrays,Delphi Xe4,我正在尝试使用下面代码中的StringOf函数创建字符串。为什么在用于创建字符串的数组Showmessage上的ZeroMemory之后不显示任何内容。为什么?在注释的ZeroMemory中,将显示大小写=== TIdBytes = array of Byte; procedure fill(var b: TIDBytes); begin setlength(b,5); b[0]:=61; b[1]:=61; b[2]:=61; b[3]:=61; b[4]:=61; end; proce
StringOf
函数创建字符串。为什么在用于创建字符串的数组Showmessage
上的ZeroMemory
之后不显示任何内容。为什么?在注释的ZeroMemory
中,将显示大小写===
TIdBytes = array of Byte;
procedure fill(var b: TIDBytes);
begin
setlength(b,5);
b[0]:=61;
b[1]:=61;
b[2]:=61;
b[3]:=61;
b[4]:=61;
end;
procedure TMainForm.FormCreate(Sender: TObject);
var
POSSaleTransaction: TPOSSaleTransaction;
s: ansistring ;
b:TIDBytes;
begin
fill(b);
s := StringOf( TArray<byte>(b) );
ZeroMemory(@b, Length(b));
Showmessage(s);
end;
TIdBytes=字节数组;
过程填充(变量b:TIDBytes);
开始
设定长度(b,5);
b[0]:=61;
b[1]:=61;
b[2]:=61;
b[3]:=61;
b[4]:=61;
终止
程序TMAInformCreate(发送方:ToObject);
变量
POSSaleTransaction:tpossaleTransaleTransaction;
s:翻译;
b:TIDBytes;
开始
填充(b);
s:=StringOf(TArray(b));
零内存(@b,长度(b));
显示讯息;
终止
我使用的是Delphi XE4
我尝试将内存归零的原因是,我不想100%地相信新创建的字符串不是使用字节[]的引用,而是复制b数据。借助ZeroMemory,我正在删除
b
的内容,同时希望它不会对字符串产生影响 您刚刚把堆栈变量吹到了那里。B
指针(整体)和部分指针S
((长度(B)-SizeOf(B))
字节)
什么是b
?它是一个复杂的结构,一个句柄,一个指针。通常,您不希望破坏内存结构,而是希望将数据放入单元格中。但在您的示例中,您只是删除了堆栈上分配的所有内存结构。可能包括字符串本身
以下程序在Delphi XE2中按预期工作-查看内存不是零,而是有什么。当您想使用低级技巧作为原始指针(或非类型化变量,如ZeroMemory
)时,请阅读Delphi中的动态数组是什么,以及如何从CPU汇编程序的角度分配它们
见手册
UniqueString
StringOf
手册-它返回一个UnicodeString
临时隐藏变量。该变量在XE4中以UTF-16
编码,这意味着每个字母有2个字节,这意味着原始字节链无论如何都不适合,并将转换为新的缓冲区
之后,将UnicodeString
临时隐藏变量转换为AnsiString
变量s
,每个字母有一个字节,因此它也不能引用temp var,但会分配另一个独立的缓冲区来保存转换后的数据
正如您所看到的,有两个必要的copy-with-transformation操作,这两个操作都使保留数据引用变得不可能。您刚刚在那里吹掉了堆栈变量。
B
指针(整体)和部分指针S
((长度(B)-SizeOf(B))
字节)
什么是b
?它是一个复杂的结构,一个句柄,一个指针。通常,您不希望破坏内存结构,而是希望将数据放入单元格中。但在您的示例中,您只是删除了堆栈上分配的所有内存结构。可能包括字符串本身
以下程序在Delphi XE2中按预期工作-查看内存不是零,而是有什么。当您想使用低级技巧作为原始指针(或非类型化变量,如ZeroMemory
)时,请阅读Delphi中的动态数组是什么,以及如何从CPU汇编程序的角度分配它们
见手册
UniqueString
StringOf
手册-它返回一个UnicodeString
临时隐藏变量。该变量在XE4中以UTF-16
编码,这意味着每个字母有2个字节,这意味着原始字节链无论如何都不适合,并将转换为新的缓冲区
之后,将UnicodeString
临时隐藏变量转换为AnsiString
变量s
,每个字母有一个字节,因此它也不能引用temp var,但会分配另一个独立的缓冲区来保存转换后的数据
正如您所看到的,有两种必要的“带转换的复制”操作,这两种操作都使保留数据引用变得不可能。您可能希望这样做:
ZeroMemory(@b[0], Length(b));
而不是
ZeroMemory(@b, Length(b));
请记住
b
变量仅为4字节大小的指针,并指向字节数组。您可能需要执行以下操作:
ZeroMemory(@b[0], Length(b));
而不是
ZeroMemory(@b, Length(b));
请记住
b
变量仅为4字节大小的指针,并指向字节数组。ZeroMemory
不会释放内存。它将零字节写入您提供的内存块中
即使这样,您的代码也会出错。在代码中,b
是指向动态数组的指针。您将@b
传递给ZeroMemory
,这样您就可以将指针归零,而不是它所指向的数组。由于您传递的字节计数值大于SizeOf(b),因此您也在将堆栈的其他部分归零。这就是你打电话给我的原因
b := nil;
Finalize(b);
SetLength(b, 0);