Delphi 10. TCustomWinSocket 数组使用时访问冲突
Delphi 10. Array of TCustomWinSocket Access violation on usage
我正在为我的自定义 Battleship 游戏制作配对服务器。我是网络编码的初学者,所以对于愚蠢的问题,我提前表示歉意。 :P
现在接近主题了。我使用默认的 Delphi Server/Client Socket 组件。我在 public 部分 (clients: array of TCustomWinSocket;
) 中声明了数组,然后在主框架启动时将长度设置为零 (setLength(clients, 0);
)。现在让我感到困惑的部分是:每当我尝试访问数组程序的任何元素时,都会抛出一个访问冲突异常。我已经以任何已知方式检查过,程序永远不会超过数组的长度。
下面是抛出异常的代码示例:
procedure Tmain.Button1Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to length(clients) do begin
if assigned(clients[i]) then begin
showmessage(IntToStr(i));
showmessage(IntToStr(i) + ': ' + clients[i].RemoteAddress);
end;
end;
end;
另一个例子:
procedure Tmain.serverClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
addLog('(' + Socket.RemoteAddress + ':' + IntToStr(Socket.RemotePort) + ') Клиент подключился');
if length(clients) <> 0 then begin
showmessage(IntToStr(length(clients)));
setLength(clients, length(clients) + 1);
showmessage(IntToStr(length(clients)));
clients[length(clients)] := Socket;
end
else if length(clients) = 0 then begin
showmessage(IntToStr(length(clients)));
clients[0] := Socket;
end;
end;
基本上,每次我使用这个数组时都会出现访问冲突。搞不定,我把代码限制在数组长度内,结果不行。或者,也许是我一贯的愚蠢造成的?
无论如何,我真的需要一些帮助。
提前致谢! :)
您 运行 超出了此循环中数组的末尾。 Length(clients)
比最后一个索引高一个,因为动态数组的索引从零开始。您必须使用 Length(clients) - 1
或 High(clients)
作为循环的终止符。
procedure Tmain.Button1Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to High(clients) do begin // or Length(clients) - 1
if assigned(clients[i]) then begin
showmessage(IntToStr(i));
showmessage(IntToStr(i) + ': ' + clients[i].RemoteAddress);
end;
end;
end;
你的第二个代码块也有类似的错误,还有一个很清楚:
procedure Tmain.serverClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
addLog('(' + Socket.RemoteAddress + ':' + IntToStr(Socket.RemotePort) + ') Клиент подключился');
if length(clients) <> 0 then begin
showmessage(IntToStr(length(clients))); // Need - 1 or High() here
setLength(clients, length(clients) + 1);
showmessage(IntToStr(length(clients))); // Need - 1 or High() here
clients[length(clients)] := Socket;
end
else if length(clients) = 0 then begin // Second problem starts here
showmessage(IntToStr(length(clients))); // See text below
clients[0] := Socket;
end;
end;
第二个错误是在 Length(clients) = 0
时尝试分配给 clients[0]
,因为这是一个无效索引。如果数组长度为零,则没有元素0,因为数组是空的——里面没有元素——一个都没有;您不能为其中包含零个元素的数组赋值。
整个块的正确代码应该是这样的 - 您不需要两个测试,测试长度 = 0,或跳过所有的箍:
procedure Tmain.ServerClientConnect(Sender: TObject; Socket; TCustomSocket);
begin
AddLog('Whatever you want to log.');
SetLength(clients, Length(clients) + 1);
Clients[High(Clients)] := Socket;
end;
我正在为我的自定义 Battleship 游戏制作配对服务器。我是网络编码的初学者,所以对于愚蠢的问题,我提前表示歉意。 :P
现在接近主题了。我使用默认的 Delphi Server/Client Socket 组件。我在 public 部分 (clients: array of TCustomWinSocket;
) 中声明了数组,然后在主框架启动时将长度设置为零 (setLength(clients, 0);
)。现在让我感到困惑的部分是:每当我尝试访问数组程序的任何元素时,都会抛出一个访问冲突异常。我已经以任何已知方式检查过,程序永远不会超过数组的长度。
下面是抛出异常的代码示例:
procedure Tmain.Button1Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to length(clients) do begin
if assigned(clients[i]) then begin
showmessage(IntToStr(i));
showmessage(IntToStr(i) + ': ' + clients[i].RemoteAddress);
end;
end;
end;
另一个例子:
procedure Tmain.serverClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
addLog('(' + Socket.RemoteAddress + ':' + IntToStr(Socket.RemotePort) + ') Клиент подключился');
if length(clients) <> 0 then begin
showmessage(IntToStr(length(clients)));
setLength(clients, length(clients) + 1);
showmessage(IntToStr(length(clients)));
clients[length(clients)] := Socket;
end
else if length(clients) = 0 then begin
showmessage(IntToStr(length(clients)));
clients[0] := Socket;
end;
end;
基本上,每次我使用这个数组时都会出现访问冲突。搞不定,我把代码限制在数组长度内,结果不行。或者,也许是我一贯的愚蠢造成的?
无论如何,我真的需要一些帮助。
提前致谢! :)
您 运行 超出了此循环中数组的末尾。 Length(clients)
比最后一个索引高一个,因为动态数组的索引从零开始。您必须使用 Length(clients) - 1
或 High(clients)
作为循环的终止符。
procedure Tmain.Button1Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to High(clients) do begin // or Length(clients) - 1
if assigned(clients[i]) then begin
showmessage(IntToStr(i));
showmessage(IntToStr(i) + ': ' + clients[i].RemoteAddress);
end;
end;
end;
你的第二个代码块也有类似的错误,还有一个很清楚:
procedure Tmain.serverClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
addLog('(' + Socket.RemoteAddress + ':' + IntToStr(Socket.RemotePort) + ') Клиент подключился');
if length(clients) <> 0 then begin
showmessage(IntToStr(length(clients))); // Need - 1 or High() here
setLength(clients, length(clients) + 1);
showmessage(IntToStr(length(clients))); // Need - 1 or High() here
clients[length(clients)] := Socket;
end
else if length(clients) = 0 then begin // Second problem starts here
showmessage(IntToStr(length(clients))); // See text below
clients[0] := Socket;
end;
end;
第二个错误是在 Length(clients) = 0
时尝试分配给 clients[0]
,因为这是一个无效索引。如果数组长度为零,则没有元素0,因为数组是空的——里面没有元素——一个都没有;您不能为其中包含零个元素的数组赋值。
整个块的正确代码应该是这样的 - 您不需要两个测试,测试长度 = 0,或跳过所有的箍:
procedure Tmain.ServerClientConnect(Sender: TObject; Socket; TCustomSocket);
begin
AddLog('Whatever you want to log.');
SetLength(clients, Length(clients) + 1);
Clients[High(Clients)] := Socket;
end;