在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
@、^、Addr、PointerDelphi(Pascal)中有几个特殊的符号,如@、^等,弄清楚这些符号的运行,首先要明白Delphi指针的一些基础知识:指针,是一个无符号整数(unsigned int),它是一个以当前系统寻址范围为取值范围的整数。指针对应着一个数据在内存中的地址,得到了指针就可以自由地修改该数据。指针的指针就是用来存放指针所在的内存地址的。
通过这段代码则更容易区分它们: var X, Y: Integer; // X and Y 整数类型 P: ^Integer; // P 指向整数类型的指针 begin X := 11; // 给 X 赋值 P := @X; // 把 x的地址赋给p Y := P^; // 取出p所指向的数值赋给y end; 第二行定义了两个变量X,Y。 第三行声明了P是指向整数类型的指针;意味着P能够指向X或者Y的地址。第五行赋给X值,第六行把X的地址赋给P。最后通过P指向的变量赋值给Y。此时,X和Y有相同的值。 Char、Byte
虽然字符实质上也是整数,但与C不同,Delphi中将他们划为两种不同的类型,各自遵从不同的运算。比如运算符+对于Byte是整数加法,对于Char则是字符连接成串。 Move、CopyMemoryMove字面意思上是“移动”的意思,其实不然,在Delphi中Move更像是Copy:它可以复制一段内存片段到另外一段内存空间中。如下代码: var source, dest : string; begin // Set up our starting string source := '123456789'; dest := '---------'; // Copy a substring from source into the middle of dest Move(source[5], dest[3], 4); // Show the source and destination strings ShowMessage('Source = '+source); ShowMessage('Dest = '+dest); end; //结果------------------ //Source = 123456789 //Dest = --5678--- //而CopyMemory则可以在Delphi的源码中看出端倪 procedure CopyMemory(Destination: Pointer; Source: Pointer; Length: DWORD); begin Move(Source^, Destination^, Length); end; 可以看出,CopyMemory其实也是调用了Move方法,但参数变了,CopyMemory参数是指针。当然,从源码还可以发现MoveMemory和CopyMemory是一模一样的功能。 var buf1,buf2: array[0..9] of AnsiChar; begin buf1 := '0123456789'; buf2 := 'abcdefghij'; CopyMemory(@buf2[2], @buf1[4], 5); ShowMessage(buf1); {0123456789} ShowMessage(buf2); {ab45678hij} end; GetMem和FreeMem、GetMemory和FreeMemory、New和Dispose、StrAlloc和StrDispose、AllocMemDelphi中的内存申请和释放方法比较多,但有一点儿需要牢记的是上述方法建议配对使用。 function GetMemory(Size: Integer): Pointer; cdecl; begin Result := MemoryManager.GetMem(Size); end; function FreeMemory(P: Pointer): Integer; cdecl; begin if P = nil then Result := 0 else Result := MemoryManager.FreeMem(P); end; 因此,建议用GetMemory和FreeMemory代替GetMem和FreeMem。 TRecord = record Text: string; Value: Integer; end; PRecord = ^TRecord; 如果用GetMem和FreeMem、GetMemory和FreeMemory来释放,会造成Text的内存没有释放,造成内存泄漏。如果用Dispose来释放指针,要加上定义信息,否则造成内存泄漏,正确写法Dispose(PRecord(Point))。另外需要注意的一点是:Delphi设计的Dispose释放内存时,只是标记这部分内存可以再用来被New等函数分配,并不是把从系统申请到的内存归还给操作系统,只在程序结束时,才全部释放给操作系统,因此并不能在资源管理器中看到Dispose的“显著效果”。 Type PMyRec = ^TMyRec; TMyRec = record FName: string; LName: string; end; var MyRecPtr: PMyRec; TreeViewIndex: LongInt; begin New(MyRecPtr); MyRecPtr^.FName := Edit1.Text; MyRecPtr^.LName := Edit2.Text; {其他处理} Dispose(MyRecPtr); end; StrAlloc和StrDispose这个函数也是一对,他们分配PChar加一个Cardinal长度,因此一定要用StrDispose释放,否则容易造成4字节的内存泄漏。StrAlloc分配的指针可以使用StrBufSize来获得大小。 https://www.cnblogs.com/chenmfly/p/4818347.html |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论