1

このようなループでコンポーネントを作成したら、どうすればコンポーネントを適切に解放できますか?今のように解放すると、GETMEM.INC例外が発生します。私はインディ出身なので、ICSについてはあまり知りません。

ありがとう

  const
    URLs : array[0..3] of string =
    (
      'http://www.example.com',
      'http://www.example.com',
      'http://www.example.com',
      'http://www.example.com'
    ) ;

    var
      Output: array of TStringList;
      S: array of TMemoryStream;
      Async: array of TSslHttpCli;
    implementation

    procedure RequestDone(Sender: TObject; RqType: THttpRequest;
      ErrCode: Word);
    begin
        with Sender as TSSLHTTPCLI do  begin
          S[Tag].Position:=0;
          Output[Tag].LoadFromStream(S[Tag]);
        end;
      end;


    procedure TForm1.Button1Click(Sender: TObject);
    var
    i:integer;
    begin
        for i := 0 to High(URLS) do begin
           S[i]:=TMemoryStream.Create;
           Output[i]:=TStringList.Create;
           Async[i]:=TSslHttpCli.Create(nil);
           Async[i].Tag:=i;
           Async[i].FollowRelocation:=true;
           Async[i].NoCache:=true;

           Async[i].SocketFamily:=sfAny;
           Async[i].OnRequestDone:=RequestDone;
           Async[i].RcvdStream:=S[i];
           Async[i].URL:= URLs[i];
           Async[i].MultiThreaded:=true;
           Async[i].GetASync;
        end;
    end;

    procedure TForm1.Button4Click(Sender: TObject);
    var
    i:integer;
    begin
        for i := 0 to High(URLS) do begin
           Output[i].Free;
           Async[i].RcvdStream.Free;
           Async[i].Free; // << -- EXCEPTION
           //  S[i].Free;
        end;
    end;
4

1 に答える 1

2

Result、、、Asynchまたはにメモリを割り当てることはありませんSSetLengthそれらに何かを入れる(または何かを取り戻す)前に、それらのそれぞれにオンにする必要があります。

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
  SetLength(Result, Length(URLS));
  SetLength(S, Length(URLS));
  SetLength(Asynch, Length(URLS));

  for i := 0 to High(URLS) do begin
    S[i]:=TMemoryStream.Create;
    Result[i]:=TStringList.Create;
    Async[i]:=TSslHttpCli.Create(nil);

    // etc.

  end;
end;

ところで、Result変数、特にスコープがグローバルな変数のひどい名前です。これは、コンパイラによって自動的に生成される関数からの戻り値であり、関数内以外の場所で使用すると、コードが読みにくくなります。たとえば、これを参照してください。

var
  Result: string = '';

procedure AddToReslt(CharToAdd: Char);
begin
  // Many many lines of code
  // go in here. Maybe a few loops
  // of if statements.
  Result := Result + CharToAdd;
end;

function DoSomeMath: Integer;
begin
  // Some really complex numeric code, maybe
  // calculating the value of `pi` to the 900th
  // digit 
  Result := 2 * 2;
end;

さて、すぐに-それぞれにたくさんのコードが含まれていることを思い出してください-どれが関数で、どれがプロシージャですか?

于 2012-12-13T15:52:07.693 に答える