Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 从字节数组创建字符串_String_Delphi_Stack_Dynamic Arrays_Delphi Xe4 - Fatal编程技术网

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汇编程序的角度分配它们

见手册

所以下一个问题是,为什么要调用ZeroMemory,这有什么意义?soem是否试图销毁密码密钥或其他敏感数据

如果您只想确保“s”变量没有任何外部引用,那么它有一个特殊的函数,
UniqueString

然而,在这个特定的工作流和这个特定的Delphi版本中,这种情况无论如何都不会发生。再次阅读
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汇编程序的角度分配它们

见手册

所以下一个问题是,为什么要调用ZeroMemory,这有什么意义?soem是否试图销毁密码密钥或其他敏感数据

如果您只想确保“s”变量没有任何外部引用,那么它有一个特殊的函数,
UniqueString

然而,在这个特定的工作流和这个特定的Delphi版本中,这种情况无论如何都不会发生。再次阅读
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);