GetMem为一个PChar变量改变其他PChar变量的内容

时间:2011-05-21 19:56:39

标签: delphi delphi-2010 winsock winsock2 winsockets

所以,我有下面的问题。我有2个PChar变量。我首先分配内存,做一些操作,为第二个变量分配内存 - 在这一步,第一个变量包含坏值(我在调试时看到它)。这是代码:

procedure TReadThread.Execute;
Var
  iRead, temp, i, count : Integer;
  header, params : PChar;
begin
  try
    GetMem(header, 12);
    iRead := recv(FSocket, header^, 12, 0);

    if (iRead<>12) then
      raise Exception.Create('Header recieving problem!');

    temp := StrToIntDef(String(copy(header,3,4)),0);

    if (temp=0) then
      raise Exception.Create('Body receiving problem!');

    count := temp*SizeOf(Char);

    if (count+12<=16384) then
      begin
        GetMem(params, count);
        iRead := recv(FSocket, params^, count, 0);

        if (iRead<>count) then
          raise Exception.Create('Cant recieve messsage fully!');
      end
    else
      raise Exception.Create('Bad message size (>16 KB)!');

    GetMem(FText, temp*SizeOf(Char)+12);
    FText := PChar(String(header) + String(params));

    FreeMem(header);
    FreeMem(params);
  except
    on E : Exception do
      ShowMessage(E.Message);
  end;
end;

在线

iRead := recv(FSocket, params^, count, 0);

当我寻找变量HEADER值时 - 我看到了一些惊人的东西 - 当我在程序开始时看到它时不一样。我怎么解决它?

2 个答案:

答案 0 :(得分:3)

我认为FTextPChar。既然您说您使用的是Delphi 2010,那么您应该知道Char实际上是WideChar的同义词,并且宽度为2个字节。我怀疑你真的想要使用AnsiChar

最明显的问题是您为FText分配了内存,然后通过分配给FText将其丢弃。更重要的是,当程序结束时,FText引用的内存将被销毁。

我认为您应该执行以下操作:

  • 切换到AnsiCharrecv来电。
  • FText更改为AnsiString
  • 完全停止使用GetMem并使用堆栈分配。

也许是这样的:

procedure TReadThread.Execute;
Var
  iRead, count: Integer;
  header: array [0..12-1] of AnsiChar;
  params: array [0..16384-1] of AnsiChar;
begin
  try
    iRead := recv(FSocket, header, 12, 0);

    if (iRead<>12) then
      raise Exception.Create('Header receiving problem!');

    count := StrToIntDef(Copy(header,3,4),0);

    if (count=0) then
      raise Exception.Create('Body receiving problem!');

    if (count+12<=16384) then
      begin
        iRead := recv(FSocket, params, count, 0);
        if (iRead<>count) then
          raise Exception.Create('Cant receive messsage fully!');
      end
    else
      raise Exception.Create('Bad message size (>16 KB)!');

    SetLength(FText, 12+count);
    Move(header, FText[1], 12);
    Move(params, FText[13], count);
  except
    on E : Exception do
      ShowMessage(E.Message);
  end;
end;

答案 1 :(得分:0)

AS David Heffernan说道。 Char是2字节,并且pChar指向Delphi 2010中的Unicode字符。但David的代码有2个问题

  1. 如果您想获得国际字符(unicode或utf8字符串),则无法使用AnsiChar

  2. 如果将params变量定义为AnsiChar的Array [0..16384-1],那么您将失去程序性能。局部变量将使用堆栈并定义params,就像David定义的那样会消耗你的堆栈空间。

  3. 您可以使用的答案通过1个简单的更改来使用您的代码。只将您的标题和参数变量定义为PAnsiChar。你可以把其他代码保持不变。

    标题,参数:PAnsiChar;