1

TThreadListサーバーによって作成されたオブジェクトへのすべてのポインターを保持するウィッチがあります。サーバーには、そのスレッド リスト内のすべてのクライアントにデータを送信するためのスレッドのプールがあります。リストをロックし、ユーザーが切断した後にリストを解放し、オブジェクトと参照ポインターを削除します。

問題は、ソケットがいつ切断されて削除されるかがわからないスレッドのプールを使用するため、プールが機能すると、何らかの理由で既に削除されているスレッドリストから選択されたポインターで AV が発生することです。

例、プールのExecuteメソッド:

  try
    with userlist.LockList do 
    begin
      for i := Count - 1 downto 0 do
      begin
        if i >= 0 then 
        begin
          p := TClient(items[i]);
          //problem here p gets deleted so it raises items[i] 
          //have an invalid pointer to memory
          if p <> nil then
            if p.sockethex <> nil then
            begin
              sendtexthexpool(p.sockethex, msgprimit+ '|'); //here AV cause P was deleted
            end;
        end;
      end;
    end;
  finally
    userlist.UnlockList;
  end;
end;
4

1 に答える 1

6

ポインターしかない場合、それが解放されたかどうかを判断する方法はありません。この情報を追跡するには、プログラムを取得する必要があります。

古いポインターを検出できたとしても、それは役に立ちません。あなたはまだレースをするでしょう。

あなたの抜粋には、スレッドリストがあります。リストがロックされている間にポインターへのすべてのアクセスが行われる限り、問題はありません。おそらく、リストへのロックを保持せずにオブジェクトを解放しています。その問題を修正すると、すべてがうまくいくはずです。

于 2013-01-18T14:31:27.780 に答える