2025年关于PChar和指针

关于PChar和指针对于刚开始学编程的人来说 指针无疑是最大的恐惧和进步障碍了 我本人也是如此 居然毕业 1 年后还是见到 就怕的要命 其实现在想来 其实指针变不是什么难的东西 而且灵活运用它能有带来许多便利 很多人把指针比喻成门牌号码 这个比喻是再恰当不过了 一个门牌号码你当然看不到 这个门牌所对应的具体的是哪个房子哪栋楼是什么样的吧 指针也一样

大家好,我是讯享网,很高兴认识大家。

  对于刚开始学编程的人来说,指针无疑是最大的恐惧和进步障碍了. 我本人也是如此,居然毕业1年后还是见到^就怕的要命.其实现在想来,其实指针变不是什么难的东西,而且灵活运用它能有带来许多便利,很多人把指针比喻成门牌号码,这个比喻是再恰当不过了,一个门牌号码你当然看不到,这个门牌所对应的具体的是哪个房子哪栋楼是什么样的吧,指针也一样,在win32里它也只是一个占4个字节(32位)的数字,而这个数字对应的内存具体所保存的是什么东西,你不去访问它是不知道的.

  很多人在写要提供其他语言调用的dll的时候,知道要用pchar来做为字符串,我就以pchar来做一些简单的介绍吧.

首先我们来看一下pchar的定义:在随便哪个事件里定义一个P:PChar将鼠标放到PChar上,可以看到type System.PChar=^Char可以看到PChar就是一个指向Char类型的指针,另外PAnsiChar类型的也可以看到type System.PAnsiChar:PChar 所以你应该以后不会问PAnsiChar和PChar有什么不同了吧.

既然是指针,如果要使用就要给它分配内存,或者将它指向一个已经分配了的内存.我们先来看给PChar分配内存的函数,delphi提供了一个叫StrAlloc的函数来给null-terminated string类型的字符串分配内存,该函数可以用来给PChar分配size(参数)字节的内存,并将PChar指向第一个字符.知道它的作用,我们再来看下它的源代码(按住Ctrl点函数):

function StrAlloc(Size: Cardinal): PChar;
begin
  Inc(Size, SizeOf(Cardinal));
  GetMem(Result, Size);
  Cardinal(Pointer(Result)^) := Size;
  Inc(Result, SizeOf(Cardinal));
end;

一句来解释下,Inc(Size, SizeOf(Cardinal));将要分配的内存加上一个Cardinal的长度,为什么后面再说

GetMem(Result, Size);分配size长度的内存,并将Result指向这块内存开头,注意GetMem分配的都是堆内存.


讯享网

Cardinal(Pointer(Result)^) := Size;将Result指向的内存的前4个字节填上Size的大小.

来看这样一段程序:

var
  P:PChar;
  S:String;
begin
  S:='aaaa';
  try
    P:=StrAlloc(1024);
    //P:=StrPCopy(P,S);
    P:=PChar(S);
    Showmessage(P);
    Showmessage(InttoStr(Length(P)));
  finally
    StrDispose(P);
  end;
end;

以上代码运行会发现StrDispose(P);这句会报Invalid pointer operation,非法的指针操作,为什么呢?

因为P:=PChar(S);这句已经将P指向一个局部变量的内存,而它的分配和释放是由delphi编译器来管理的,你无法操作的,而你原来申请的1024个字节的内存已经泄露了.所以指针操作里千万不要再创建内存后又重新指向另外一个地方.前2天有个人问我,2个PChar的字符能不能连接直接用+来,也许你该想想,2个门牌号码的数字加起来是不是就是代表这2个房间呢? 

小讯
上一篇 2025-04-01 17:57
下一篇 2025-04-08 23:56

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/41430.html