TMemoryStream中Buffer.Memory与@Buffer.Memory^的区别是什么?
嘿,这俩问题都是Delphi里指针操作的经典疑惑,我来给你掰扯清楚:
1. @Buffer.Memory^ 与 Buffer.Memory 的通用区别
首先得先搞懂Delphi里两个核心操作符的含义:
^:指针解引用符,用来获取指针指向的内存里的实际数据@:取地址符,用来获取某个变量/数据所在的内存地址
具体区别得看Buffer.Memory的类型:
- 如果
Buffer.Memory是指针类型:Buffer.Memory就是指针本身,存储的是一段内存地址Buffer.Memory^是这个指针指向的内存里的实际值@Buffer.Memory^则是这个实际值所在的内存地址——说白了,它和Buffer.Memory的数值是完全一样的,只是多了“解引用再取地址”的操作步骤
- 如果
Buffer.Memory是非指针类型(比如Integer、Byte这类值类型):Buffer.Memory^这种写法直接会编译报错,因为只有指针才能用^解引用;这时候只有@Buffer.Memory是合法的,用来取这个值的内存地址
2. 当Buffer为TMemoryStream时,@Buffer.Memory^ 与 Buffer.Memory 的区别
先明确:TMemoryStream的Memory属性是Pointer类型,指向的是流中存储数据的起始内存地址。咱们结合实际代码来拆解:
Buffer.Memory:直接拿到的就是这个Pointer本身,也就是流数据的起始地址,类型是PointerBuffer.Memory^:对这个无类型指针解引用,获取的是该地址处的第一个字节的数据(因为无类型指针默认按Byte解析)@Buffer.Memory^:取刚才解引用得到的那个字节的内存地址——结果和Buffer.Memory完全一样,因为那个字节就存在Buffer.Memory指向的地址上
举个直观的代码例子:
var MS: TMemoryStream; StreamAddr: Integer; FirstByte: Byte; begin MS := TMemoryStream.Create; try FirstByte := $A5; MS.WriteBuffer(FirstByte, SizeOf(FirstByte)); // 往流里写入一个字节0xA5 StreamAddr := Integer(MS.Memory); // 获取流数据的起始地址,比如$00456789 FirstByte := MS.Memory^; // 拿到流里的第一个字节,值为$A5 // 对比地址:@MS.Memory^ 就是FirstByte所在的地址,也就是流的起始地址 ShowMessage(IntToHex(Integer(@MS.Memory^), 8)); // 输出和StreamAddr完全相同的地址 finally MS.Free; end; end;
总结下:在TMemoryStream场景里,@Buffer.Memory^和Buffer.Memory的数值完全相等,但前者是绕了个弯(解引用再取地址),后者是直接拿指针,显然后者更高效简洁,除非有特殊的类型转换需求,否则没必要用前者。
内容的提问来源于stack exchange,提问作者zeus
相关产品推荐
相关产品推荐

