C++ 在SFML中使用TcpSocket发送数据会导致分段错误

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::

我正在使用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::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;
--a
char**
不是
char
的二维数组。这是代码中的一个巨大错误,假设它们是同样。删除所有
char**
usage,创建一个具有简单
char[3][3]的结构
在其中。简言之,.使内部数组成为可以使用结构包装器传递的数组。我不知道这是否是唯一的问题,但这是一个需要解决的问题。
char**data;
--a
char**
不是一个二维数组的
char
。这是代码中的一个巨大错误,这就是ass如果它们都是一样的,请删除所有的
char**
用法,创建一个包含简单
char[3][3]
的结构。简而言之,使用结构包装器可以传递内部数组。我不知道这是否是唯一的问题,但这是一个需要解决的问题。