c - 如何在此代码中处理部分 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;
}
这也会产生同样的问题。
解决方案
正如其他海报指出的那样,您不应该realloc()
修改指针。tmp
被初始化为recv_buf
。但是tmp
被修改为tmp = tmp + ret_recv
,而您正在尝试realloc()
修改tmp
为newp = 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 个字节左右)。
推荐阅读
- amazon-web-services - 查明 FCM 推送通知状态“成功”但未在控制台/设备中收到
- r - 如何使用 R 及时创建快照
- php - 我可以做些什么来清理我的 php 文件以不包括其中的 html 和 css?
- c - ESP-WROOM-02D 无法使用 AT 命令进行通信
- javascript - 如何降低此开关盒的复杂性?
- r - 如何创建一个循环或函数来循环遍历包含变量的两个向量列表以对响应运行 KS 测试
- r - 如何在 R 中运行循环以进行后向消除以进行回归
- iis - 更改 IIS 8 中配置文件的路径
- c++ - const char* 到一个文件名字符串,以将 10 个不同的 .pgm 文件读入二维数组
- c# - 使用反射从“System.Int32”到枚举的无效转换