我在线程中在XE/XE2中使用SOAP时遇到问题。 (我没有使用较早的Delphis进行测试。)在Invalid pointer operation破坏THTTPReqResp实例的同时,在主线程中工作的简单代码崩溃。

这是完整的程序。该表单仅包含一个触发btnTestClick事件的按钮:

unit Unit79;

interface

uses
  SysUtils, Forms, Classes, Controls, StdCtrls, ComObj,
  ActiveX, InvokeRegistry, SOAPHTTPTrans, Rio, SOAPHTTPClient;

type
  TForm79 = class(TForm)
    btnTest: TButton;
    procedure btnTestClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form79: TForm79;

implementation

{$R *.dfm}

procedure TForm79.btnTestClick(Sender: TObject);
begin
  TThread.CreateAnonymousThread(
    procedure
    var
      FHTTPReqResp: THTTPReqResp;
      FHTTPRIO: THTTPRIO;
    begin
      if CoInitializeEx(NIL, COINIT_MULTITHREADED or COINIT_SPEED_OVER_MEMORY) = S_OK then try
        FHTTPReqResp := THTTPReqResp.Create(nil);
        with FHTTPReqResp do begin
          Name := 'HTTPReqResp1';
          UseUTF8InHeader := True;
          InvokeOptions := [soIgnoreInvalidCerts, soAutoCheckAccessPointViaUDDI];
          WebNodeOptions := [];
        end;
        FHTTPRIO := THTTPRIO.Create(nil);
        with FHTTPRIO do begin
          Name := 'HTTPRIO1';
          HTTPWebNode := FHTTPReqResp;
        end;
        //
        FreeAndNil(FHTTPRIO);
        FreeAndNil(FHTTPReqResp); //<-- crashes here
      finally CoUninitialize; end;
    end
  ).Start;
end;

end.

_FreeMem调用中的TObject.FreeInstance中引发了异常。
procedure TObject.FreeInstance;
begin
  CleanupInstance;
  _FreeMem(Self);
end;

导致此问题的调用堆栈是



我完全不知道发生了什么,为什么根本调用_ClassDestroy以及为什么代码崩溃:(有人可以请a)解释我做错了什么,b)修复我的代码吗?

最佳答案

“无效的指针操作”表示您正在释放不代表有效内存的内容。有时这可能表明堆栈或堆已损坏,但更有可能表明您正在释放已释放的内容。

调用_ClassDestroy并不奇怪。 FHTTPReqResp是非null的,因此,当FreeAndNil对其调用Free时,Free会调用Destroy

您的THTTPRIO对象似乎已获得您提供的THTTPReqResp的所有权。如果真是这样,那么解决方案很简单:不要自己释放它。

关于multithreading - 无法销毁线程中的THTTPReqResp组件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8885455/

10-11 18:00