代码在下面,test1和test2其实是完全相同的,循环多次执行时发现会报下面的错,请教这是什么原因?Project Project1.exe raised exception class EInvalidPointer with message 'Invalid pointer operation'. Process stopped. Use Step or Run to continue.unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons;type
  TForm1 = class(TForm)
    Edit2: TEdit;
    btnTest1: TBitBtn;
    ListBox1: TListBox;
    procedure btnTest1Click(Sender: TObject);
  private
    function test1(str:string):string;
    function test2(str:string):string;
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}
           
procedure TForm1.btnTest1Click(Sender: TObject);
var
    backvalue : String;
    i : Integer;
begin
    for i:=0 to 10 do
    begin
        ListBox1.Items.Add(IntToStr(i));
        test1(Edit2.Text);
        test2(Edit2.Text);
    end;end;function TForm1.test1(str:string):string;
var
  mychar : Array[0..0] of char;
  i,len : Integer;
  substr : String;
begin
    Result := '1';
    if (str <> '') then
    begin
        len := Length(str);
        for i:= 1 to len do
        begin
            substr := Copy(str,i,1);
            StrPCopy(mychar,substr);
            if not(mychar[0] in ['0'..'9'])then
            begin
              Result := '-1';
              break;
            end;
        end;
    end;
end;
function TForm1.test2(str:string):string;
var
  mychar : Array[0..0] of char;
  i,len : Integer;
  substr : String;
begin
    Result := '1';
    if (str <> '') then
    begin        len := Length(str);
        for i:= 1 to len do
        begin
            substr := Copy(str,i,1);
            StrPCopy(mychar,substr);
            if not(mychar[0] in ['0'..'9',#46])then
            begin
              Result := '-1';
              break;
            end;
        end;    end;
end;
end.

解决方案 »

  1.   

    StrPCopy(mychar,substr); 出现了错误~~如下测试代码 :procedure TForm1.Button5Click(Sender: TObject);
    var pc:PChar;
        str:string;
    begin
      str:='1';
      GetMem(pc,3);
      pc[0]:=chr(65);
      pc[1]:=chr(65);
      pc[2]:=chr(65);  Memo1.Lines.Add(inttostr(ord(pc[0])));
      Memo1.Lines.Add(inttostr(ord(pc[1])));
      Memo1.Lines.Add(inttostr(ord(pc[2])));  StrPCopy(pc, str);  Memo1.Lines.Add(inttostr(ord(pc[0])));
      Memo1.Lines.Add(inttostr(ord(pc[1])));
      Memo1.Lines.Add(inttostr(ord(pc[2])));  FreeMem(pc);
    end;可见 StrPCopy 拷贝了 str 的两位~~
      

  2.   


    嗯,确实是这么回事,我刚才自己也试着用PCHAR代替char数组,结果不报错了。可是如果我要继续使用char数组的话,要如何修改呢?为什么会读到str的两位?
      

  3.   

          //StrPCopy(mychar, substr);
          mychar[0]:= substr[1];
    改成这样看看
      

  4.   


    改了,真得可以。可是还是不明白,为何使用strPCopy会有问题?
      

  5.   

    substr的长度只有1个,StrPCopy却要复制2个,就要访问其他不可预知的内存了,出现错误就属于正常了
      

  6.   

    因为 你 “mychar : Array[0..0] of char;” 长度只有1啊,你弄2位或以上 就应该不报错了~~~
      

  7.   

    谢谢两位,可是我现在就是弄不明白,StrPCopy为何复制了两位呀,  str:='1';这样明明长度为1呀,StrPCopy过去后为何会多一个0?
      

  8.   

    有两种改法第一种unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Edit2: TEdit;
        Button1: TButton;
        ListBox1: TListBox;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        function test1(str: string): string;
        function test2(str: string): string;
      end;var
      Form1: TForm1;implementation{$R *.dfm}{ TForm1 }function TForm1.test1(str: string): string;
    var
      mychar: array[0..0] of char;
      i, len: Integer;
      substr: Char;
    begin
      Result := '1';
      if (str <> '') then
      begin
        len := Length(str);
        for i := 1 to len do
        begin
    //      substr := Char(Copy(str, i, 1));
          substr := str[i-1];
          StrPCopy(mychar, substr);
          if not (mychar[0] in ['0'..'9']) then
          begin
            Result := '-1';
            break;
          end;
        end;
      end;
    end;function TForm1.test2(str: string): string;
    var
      mychar: array[0..0] of char;
      i, len: Integer;
      substr: Char;
    begin
      Result := '1';
      if (str <> '') then
      begin    len := Length(str);
        for i := 1 to len do
        begin
    //      substr := Copy(str, i, 1);
          substr := str[i-1];
          StrPCopy(mychar, substr);
          if not (mychar[0] in ['0'..'9', #46]) then
          begin
            Result := '-1';
            break;
          end;
        end;
      end
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      backvalue: string;
      i: Integer;
    begin
      for i := 0 to 10 do
      begin
        ListBox1.Items.Add(IntToStr(i));
        test1(Edit2.Text);
        test2(Edit2.Text);
      end;
    end;end.第二种
    [code=Delphi(Pascal)]
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        Edit2: TEdit;
        Button1: TButton;
        ListBox1: TListBox;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        function test1(str: string): string;
        function test2(str: string): string;
      end;var
      Form1: TForm1;implementation{$R *.dfm}{ TForm1 }function TForm1.test1(str: string): string;
    var
      mychar: array[0..1] of char;
      i, len: Integer;
      substr: string;
    begin
      Result := '1';
      if (str <> '') then
      begin
        len := Length(str);
        for i := 1 to len do
        begin
          substr := Copy(str, i, 1);
          StrPCopy(mychar, substr);
          if not (mychar[0] in ['0'..'9']) then
          begin
            Result := '-1';
            break;
          end;
        end;
      end;
    end;function TForm1.test2(str: string): string;
    var
      mychar: array[0..1] of char;
      i, len: Integer;
      substr: string;
    begin
      Result := '1';
      if (str <> '') then
      begin    len := Length(str);
        for i := 1 to len do
        begin
          substr := Copy(str, i, 1);
          StrPCopy(mychar, substr);
          if not (mychar[0] in ['0'..'9', #46]) then
          begin
            Result := '-1';
            break;
          end;
        end;
      end
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      backvalue: string;
      i: Integer;
    begin
      for i := 0 to 10 do
      begin
        ListBox1.Items.Add(IntToStr(i));
        test1(Edit2.Text);
        test2(Edit2.Text);
      end;
    end;end.[/code]