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

发布于 2024-11-08 21:17:08 字数 1225 浏览 4 评论 0原文

所以,我有以下问题。我有 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 值时 - 我看到了一些令人惊奇的东西 - 与我在程序开始时看到的不一样。我该如何修复它?

So, I have the folowing problem. I have 2 PChar variables. I allocate memory for first, do some operations, allocate memory for the second variable - and on this step the first variable contains bad value (i saw it while debugging). Here is the code:

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;

On the line

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

When I look for the variable HEADER value - I saw somethind amazing - not the same when I saw at the beginning of the procedure. How I can fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧梦荧光笔 2024-11-15 21:17:08

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

最明显的问题是您为 FText 分配内存,然后通过对 FText 的分配将其丢弃。此外,当程序结束时,FText 引用的内存也会被销毁。

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

  • 切换到 AnsiChar 进行 recv 调用。
  • 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;

I presume that FText is a PChar. Since you say that you are using Delphi 2010, you should be aware that Char is actually synonymous with WideChar and is 2 bytes wide. I suspect you really want to be using AnsiChar.

The most glaring problem is that you allocate memory for FText and then discard it with the assignment to FText. What's more, the memory that FText refers to is destroyed when the procedure ends.

I think that you should probably do the following:

  • Switch to AnsiChar for the recv calls.
  • Change FText into AnsiString.
  • Stop using GetMem altogether and use stack allocation.

Perhaps something like this:

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;
恍梦境° 2024-11-15 21:17:08

正如大卫·赫弗南之前所说。 Char 是 2 个字节,pChar 在 Delphi 2010 中也指向 Unicode 字符。但是 David 的代码有 2 个问题

  1. 如果你想获取国际字符(unicode 或 utf8 字符串),你不能使用 AnsiChar

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

对于答案,您可以通过 1 个简单的更改来使用您的代码。仅将标头和参数变量定义为 PAnsiChar。其他代码不变即可。

标头,参数:PAnsiChar;

AS David Heffernan Said befor. Char is 2 byte and also pChar point to a Unicode char in Delphi 2010. but the code of David has 2 problems

  1. If you want to get the international chars (unicode or utf8 strings) you can not use the AnsiChar

  2. If define params variable as Array [0..16384-1] of AnsiChar then you will lost your program performance. local variables will use the stack and define the params like as David defined will consume your stack space.

for the answer you can use use your code by 1 simple changes. only define your header and params variable as PAnsiChar. you can put the other codes unchanged.

header, params: PAnsiChar;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文