1

だから、私は次の問題を抱えています。2つのPChar変数があります。最初にメモリを割り当て、いくつかの操作を行い、2番目の変数にメモリを割り当てます-このステップで、最初の変数に不正な値が含まれています(デバッグ中に見ました)。コードは次のとおりです。

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値を探すと、手順の最初に見たときと同じではなく、驚くべきことがわかりました。どうすれば修正できますか?

4

2 に答える 2

3

だと思いFTextますPCharCharDelphi 2010 を使用しているとのことなので、これは実際には と同義でWideCharあり、2 バイト幅であることに注意してください。私はあなたが本当に使いたいと思っていると思いますAnsiChar

最も明白な問題は、メモリをFTextに割り当ててから、 への代入で破棄することFTextです。しかも、参照先のメモリFTextは手続き終了時に破棄されます。

おそらく次のことを行う必要があると思います。

  • AnsiChar通話用に切り替えrecvます。
  • に変更FTextAnsiStringます。
  • 使用を完全に停止し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;
于 2011-05-21T20:27:38.087 に答える