realloc导致释放对象的校验和不正确

时间:2014-03-03 03:42:10

标签: c sockets memcpy realloc

这是我的套接字客户端的一部分,接收缓冲区小于服务器的发送缓冲区,所以我需要重新分配缓冲区,但它会抛出这样的错误:

malloc: *** error for object 0x7fd44ad00018: incorrect checksum for freed object - object was probably modified after being freed.

我的代码:

char recv_buf[MAX_RECV_LINE] = "";
while (fgets(buf, MAX_SEND_LINE, stdin) != NULL) {  
    write(servfd, buf, strlen(buf));
    char *recv_data = malloc(MAX_RECV_LINE);
    bzero(recv_data, MAX_SEND_LINE);
    int recv_size = 0;
    while (1) {
        FD_ZERO(&readfds);
        FD_SET(servfd, &readfds);
        select(servfd + 1, &readfds, NULL, NULL, &timeout);
        if (FD_ISSET(servfd, &readfds)) {
            bzero(recv_buf, MAX_RECV_LINE);
            size_t recv_buf_len = recv(servfd, recv_buf, MAX_RECV_LINE, 0);
            if (recv_buf_len == 0) {
                printf("Server is closed.\n");
                close(servfd);
                exit(0);
            }

            recv_data = realloc(recv_data, recv_size + recv_buf_len);
            if (recv_data == NULL) {
                exit(0);
            }
            printf("realloc: %lu\n", recv_size + recv_buf_len);
            memcpy(recv_data + recv_size, recv_buf, recv_buf_len);

            recv_size += recv_buf_len;
        } else {
            break;
        }
    }
    printf("total count: %d\n", recv_size);
    printf("Message: %s", recv_data);
    free(recv_data);
}

和recv_data无法获得完整的消息

2 个答案:

答案 0 :(得分:2)

char *recv_data = malloc(MAX_RECV_LINE);
bzero(recv_data, MAX_SEND_LINE);

问题出在这里。您正在分配一个大小为MAX_RECV_LINE的缓冲区,但将其归零为MAX_SEND_LINE的长度,您说这个长度更大。实际上您根本不需要将其归零:您的代码似乎正确处理接收到的数据。只需完全删除bzero()来电即可。

但是在两端使用相同的缓冲区大小会简单得多。我总是使用8192。

答案 1 :(得分:0)

两个建议:

  • 您不会检查recv_buf_len是否为负数(例如来自信号)。其类型应为ssize_t,而不是size_t

  • IIRC,每次拨打timeout时都需要重做select(但这不是导致问题的原因)。