C++ 在SFML中使用TcpSocket发送数据会导致分段错误
我正在使用SFML的C++ 在SFML中使用TcpSocket发送数据会导致分段错误,c++,sockets,sfml,C++,Sockets,Sfml,我正在使用SFML的TcpSocket类来发送和接收数据,但由于某种原因,我不断得到错误Segmentation fault:11。以下是服务器类: #include "ServerGame.hpp" ServerGame::ServerGame() { } void ServerGame::sendData(char data[3][3]) { if (client.send(data, 9) != sf::Socket::Done) { //std::
TcpSocket
类来发送和接收数据,但由于某种原因,我不断得到错误Segmentation fault:11
。以下是服务器类:
#include "ServerGame.hpp"
ServerGame::ServerGame()
{
}
void ServerGame::sendData(char data[3][3])
{
if (client.send(data, 9) != sf::Socket::Done)
{
//std::cout << "error" << std::endl;
}
}
void ServerGame::connect()
{
sf::TcpListener listener;
// bind the listener to a port
if (listener.listen(666) != sf::Socket::Done)
{
std::cout << "error" << std::endl;
}
// accept a new connection
if (listener.accept(client) != sf::Socket::Done)
{
std::cout << "error" << std::endl;
}
}
char** ServerGame::receiveData()
{
char **data;
data = new char*[3];
for(int i = 0; i < 3; ++i)
{
data[i] = new char[3];
}
std::size_t received;
// TCP socket:
if (client.receive(data, 9, received) != sf::Socket::Done)
{
// error...
}
return data;
}
这是启动客户端并接收数据的主类:
#include "ClientGame.hpp"
int main()
{
ClientGame cg;
cg.connect();
char** arr = cg.receiveData();
std:: cout << arr[0][0] << std::endl;
}
#包括“ClientGame.hpp”
int main()
{
客户端游戏cg;
cg.connect();
char**arr=cg.receiveData();
std::cout一个问题是假设char**
与char
的二维数组相同。它们是不相同的
执行此操作时:
char **data;
data = new char*[3];
for(int i = 0; i < 3; ++i)
{
data[i] = new char[3];
}
换句话说,这些行散布在堆内存中,并且不是连续的
因此,当您调用此函数时:
if (socket.receive(data, 9, received) != sf::Socket::Done)
socket.receive
函数需要9个字节的连续缓冲区,但您没有提供。receive
函数很可能会覆盖第一行,最多有6个字节从第一行的边缘脱落(第一行被分配为只有3个字节),从而溢出到内存中,导致分段错误
我认为问题源于您试图在函数之间传递二维数组,并使用char**
代替实际的二维数组而犯错误
为了简化操作而不必引入指针,请创建一个包含二维char
数组的struct
,然后在函数之间传递该结构
struct char2D
{
char myArray[3][3];
};
然后,不要使用char**
,只需使用char2D
的实例,并在需要时引用内部数组即可
例如:
char2D ClientGame::receiveData()
{
char2D data;
std::size_t received;
if (socket.receive(&data.myArray[0][0], 9, received) != sf::Socket::Done)
{
std::cout << "error" << std::endl;
}
return data;
}
之所以这样做,是因为结构是可复制和可分配的。因此,只要按值传递内部数组并按值返回,内部数组就会被复制。一个问题是假设char**
与char
的二维数组相同。它们是不相同的
执行此操作时:
char **data;
data = new char*[3];
for(int i = 0; i < 3; ++i)
{
data[i] = new char[3];
}
换句话说,这些行散布在堆内存中,并且不是连续的
因此,当您调用此函数时:
if (socket.receive(data, 9, received) != sf::Socket::Done)
socket.receive
函数需要9个字节的连续缓冲区,但您没有提供。receive
函数很可能会覆盖第一行,最多有6个字节从第一行的边缘脱落(第一行被分配为只有3个字节),从而溢出到内存中,导致分段错误
我认为问题源于您试图在函数之间传递二维数组,并使用char**
代替实际的二维数组而犯错误
为了简化操作而不必引入指针,请创建一个包含二维char
数组的struct
,然后在函数之间传递该结构
struct char2D
{
char myArray[3][3];
};
然后,不要使用char**
,只需使用char2D
的实例,并在需要时引用内部数组即可
例如:
char2D ClientGame::receiveData()
{
char2D data;
std::size_t received;
if (socket.receive(&data.myArray[0][0], 9, received) != sf::Socket::Done)
{
std::cout << "error" << std::endl;
}
return data;
}
之所以这样做,是因为结构是可复制和可分配的。因此,只要您按值传递内部数组并按值返回,内部数组就会被复制。char**data;
--achar**
不是char
的二维数组。这是代码中的一个巨大错误,假设它们是同样。删除所有char**
usage,创建一个具有简单char[3][3]的结构
在其中。简言之,.使内部数组成为可以使用结构包装器传递的数组。我不知道这是否是唯一的问题,但这是一个需要解决的问题。char**data;
--achar**
不是一个二维数组的char
。这是代码中的一个巨大错误,这就是ass如果它们都是一样的,请删除所有的char**
用法,创建一个包含简单char[3][3]
的结构。简而言之,使用结构包装器可以传递内部数组。我不知道这是否是唯一的问题,但这是一个需要解决的问题。