将指针转换为TBytes
我有这个代码:
procedure MyFunct(const aBin; aBinSize : Cardinal);
var bytes: Tbytes;
begin
bytes := Tbytes(@aBin);
for var I := 0 to aBinSize - 1 do
writeln(bytes[i]);
end;
var Memory: Pointer
...init the memory...
MyFunct(Memory^, sizeOfMemory);
这在几年{$R-}内运行良好(范围检查)。但是今天我决定停用{$R-},现在下面的代码因范围检查错误而崩溃,如果是,则正常,因为我这样做length(bytes)通常等于 0。
所以我可以重新激活,{$R-}但现在我认为这是一个基本错误,因为据我所知,Tbyte 的长度存储在字节 [-32bit] 处,最重要的是,Tbytes 的引用计数存储在字节 [-64bit] 处。所以现在我担心之前的代码只是以字节 [-64 位] 为单位编写了引用计数并破坏了我的记忆(可能不确定)。
所以这是一个很好的做法吗
bytes := Tbytes(@aBin);
如果不是为什么编译器授权它?如何在没有 Tbytes 的情况下浏览我内存的每个字节(即如何访问 myMemory[x])
回答
您不能TBytes像您一样将任意指针强制转换为 a ,它们是完全不同的东西。如果指向的内存不是有效的动态数组,则代码将失败。你的代码多年来一直有问题,你很幸运它没有做任何事情。
在TBytes按原样使用时,该函数需要看起来更像这样:
procedure MyFunct(const aBin; aBinSize : Cardinal);
var bytes: TBytes;
begin
SetLength(bytes, aBinSize);
Move(aBin, bytes[0], aBinSize);
for var I := 0 to aBinSize - 1 do
WriteLn(bytes[i]);
end;
否则,更简单的方法(这可能是您尝试做的)会更像这样:
procedure MyFunct(const aBin; aBinSize : Cardinal);
var bytes: PByte;
begin
bytes := PByte(@aBin);
for var I := 0 to aBinSize - 1 do
WriteLn(bytes[i]);
end;
- Which is why its unbelievable that default debug config has it turned off! See https://quality.embarcadero.com/browse/RSP-16751