从字符串流复制到 char * 数组返回为函数参数

Copying from stringstream to char * array return as function parameter

本文关键字:返回 数组 函数 参数 char 字符串 复制      更新时间:2023-10-16

我正在使用Winsock2试验HTTP协议。我正在处理一个函数

int recv_data(const char *hostname, char *resp(;

该函数旨在向给定主机发送 HTTP HEAD 请求,然后接收响应。它在指针 resp 处分配内存,并在返回响应接收的总字节数之前将响应复制到那里。

这是我的接收循环:

int recv_data(const char *hostname, char *resp)
{
    int totalRecvd = 0;
    stringstream sStream;
    while (true)
    {
        char buffer[MAX_HEADER_SIZE];
        int retValue = recv(s, buffer, MAX_HEADER_SIZE, 0);
        if (retValue == 0)
            break;  // connection has been closed
        else if (retValue == SOCKET_ERROR)
            throw RecvException("http_headreq() unable to receive data");
        else    //
        {   
            buffer[retValue] = 0; // append null terminator
            sStream << buffer;    // dump buffer into stream
            totalRecvd += retValue + 1; // tally received bytes
        }
    }
    /** Allocate and read entire read stream into memory */
    resp = new char[totalRecvd + 1];
    strcpy(resp, sStream.str().c_str());
    return totalRecvd);
}

所有这些都工作得很好,如果我在这一点上输出 resp,它会输出得很好。如果我在函数明显返回后尝试输出 resp,我只是遇到了问题。我不相信这应该是正常情况,如果我没记错的话,我相信这与我使用字符串流临时存储响应有关。我想我已经在某处读到过有关字符串流收集的数据超出范围的信息。

我希望我能以这种方式设置这个函数,调用者只需传入 char*,该函数将分配正确的内存量(在运行时根据主机和 recv(( 返回的字节数确定(。无论如何,我是否可以从内存中的字符串流中获取永久副本作为字符数组,并且在函数返回并且字符串流超出范围后指针是错误的?

[编辑]:这是下面发布的解决方案,并入了我的问题,任何希望将其重用于Winsock2扩展的人似乎都运行良好。将来自服务器接收数据,直到 recv(( 返回 0 时连接关闭。该解决方案传递对指针的引用,因为 new 运算符更改指针,并且该更改不会在函数返回后反映,除非通过引用传入。

int recv_data(SOCKET s, char *&data)
{
    int totalRecvd = 0;
    std::stringstream sStream;
    while (true)
    {
        char buffer[MAX_HEADER_SIZE];
        int retValue = recv(s, buffer, MAX_HEADER_SIZE, 0);
        if (retValue == 0)
            break;  // connection has been closed
        else if (retValue == SOCKET_ERROR)
            throw RecvException("http_headreq() unable to receive data");
        else    //
        {   
            buffer[retValue] = 0; // append null terminator
            sStream << buffer;    // dump buffer into stream
            totalRecvd += retValue + 1; // tally received bytes
        }
    }
    /** Allocate and read entire read stream into memory */
    data = new char[totalRecvd + 1];
    strcpy_s(data, totalRecvd, sStream.str().c_str());
    data[totalRecvd] = 0;
    return totalRecvd;
}

resphttp_req函数中的局部变量。更新 resp 的值在 http_req 之外没有任何效果。这一行:

resp = new char[totalRecvd + 1];

只会产生局部效果。

试试这个签名:

int http_req(const char *hostname, char *&resp);

<小时 />更好的是,尝试以C++方式返回数据:

std::string http_req(const std::string& hostname) {
    ...
    return sStream.str()
}

如果您更改代码以使用 std::stringboost::asio ,您将不再遇到内存管理问题。