首页 > 解决方案 > 如何在此代码中处理部分 recv() 中的 free 和 realloc 错误

问题描述

为了处理网络中的部分recv(),我尝试检查缓冲区,直到它通过读取从客户端发送的数据并动态分配内存然后打印消息来接收'\ n',但我遇到了错误像 realloc():无效指针 aborted()。

我处理部分读取的代码:

char *recieve_msg(int sockfd)
{
    char *newp;
    char *recv_buf;
    int recv_buf_size = 0;
    int ret_recv = 0;

    recv_buf = (char *)malloc(sizeof(char));
    while (1) { 
        ret_recv  = recv(sockfd, recv_buf, sizeof(char), 0);
        if (ret_recv == -1)
            return NULL;
        else if (ret_recv == 0)
            return  NULL;
        else if (recv_buf[recv_buf_size] == '\n')
            break;
        recv_buf_size++;
        newp = realloc(recv_buf, (recv_buf_size + 1) * sizeof(char));
        if (newp == NULL) {
            free(recv_buf);
            return NULL;
        }
        recv_buf = newp;
        recv_buf = recv_buf + ret_recv;
    }
    recv_buf[recv_buf_size] = '\0';

    return recv_buf;
}

编辑代码:

char *recieve_msg(int sockfd)
{
    char *newp;
    char *tmp;
    char *recv_buf;
    int recv_buf_size = 0;
    int ret_recv = 0;

    recv_buf = (char *)malloc(sizeof(char));
    if (recv_buf == NULL)
        return NULL;
    tmp = recv_buf;
    while (1) { 
        ret_recv  = recv(sockfd, tmp, sizeof(char), 0);
        if (ret_recv == -1)
            return NULL;
        else if (ret_recv == 0)
            return  NULL;
        else if (tmp[recv_buf_size] == '\n')
            break;
        recv_buf_size++;
        newp = realloc(tmp, (recv_buf_size + 1) * sizeof(char));
        if (newp == NULL) {
            free(tmp);
            return NULL;
        }
        tmp = newp;
        tmp = tmp + ret_recv;
    }
    tmp[recv_buf_size] = '\0';

    return recv_buf;
}

这也会产生同样的问题。

标签: clinuxunixnetworkingnetwork-programming

解决方案


正如其他海报指出的那样,您不应该realloc()修改指针。tmp被初始化为recv_buf。但是tmp被修改为tmp = tmp + ret_recv,而您正在尝试realloc()修改tmpnewp = realloc(tmp, (recv_buf_size + 1) * sizeof(char)),因此出现错误。你可以有你的代码如下:

char *recieve_msg(int sockfd)
{
    char recv_buf[1], *msg_buf = NULL;
    int recv_ret = 0, msg_len = 0;

    while (1) {
        recv_ret  = recv(sockfd, recv_buf, sizeof(recv_buf), 0);

        if (recv_ret == -1)
            return NULL;
        else if (recv_ret == 0)
            return  NULL;
        else if (recv_buf[0] == '\n')
            break;

        msg_len++;
        msg_buf = realloc(msg_buf, (msg_len + 1) * sizeof(char));

        if (msg_buf == NULL) {
            return NULL;
        }

        msg_buf[msg_len - 1] = recv_buf[0];
    }

    if (msg_buf == NULL)
        return NULL;

    msg_buf[msg_len] = '\0';

    return msg_buf;
}

撇开这个问题不谈,我强烈谴责realloc()每次recv()通话的记忆。你可以想出一些更好的方法。例如,在您的情况下,拥有一个全局缓冲区并在\n收到时对其进行操作。如果全局缓冲区即将填满,但仍未收到您的消息,则将缓冲区重新分配到更大的大小(可能多出 100 个字节左右)。


推荐阅读