2013-09-23 44 views
-1

我有这样的代码:realloc:下一个尺寸无效; memcpy的

char buf[128]; 
char *data = NULL; 
char *temp = NULL; 

int full = 0; 

int n = 0; 

do { 
    bzero(buf, sizeof(buf)); 
    n = recv(newsock, buf, sizeof(buf), 0); 

    full += sizeof(buf); 

    if(n != 0) 
      temp = realloc(data, sizeof(buf)); 

    if(temp != NULL) { 
      data = temp; 
    } else { 
     // error 
    } 

    memcpy(data + (full - sizeof(buf)), buf, sizeof(buf)); 

    printf("%s\n",data); 
} while(n > 0); 

在这段代码中我尝试从插座获取一些数据来缓冲,并把这个数据放到内存中。但我有问题。对while循环,我得到的消息是这样第三次迭代:

*** glibc detected *** ./server: realloc(): invalid next size: 0x09a4c008 *** 

当我删除的memcpy()函数一切都好,但我怎样才能把数据到内存?哪里不对?

+0

什么是'total'?我没有看到它在任何地方定义。另外(关闭主题),你如何保证'data'在传递给'printf'之前是空终止的? –

+0

select()返回文件描述符的数量,今天最好使用'memset'而不要使用'bzero' –

回答

1

问题是,你不断增加数据,但你不扩大它的内存。该行

temp = realloc(data, sizeof(buf)); 

总是分配128个字节。您需要更新它在每次迭代中将分配更多的内容。也许你打算这样做insead:

temp = realloc(data, full); 

1

我会用更多的东西是这样的:

char buf[128]; 
char *data = NULL; 
char *temp = NULL; 
int n, datalen = 0, datacap = 0; 

do 
{ 
    n = recv(newsock, buf, sizeof(buf), 0); 
    if (n < 0) 
    { 
     if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) 
     { 
      // error 
      break; 
     } 

     fd_set fdr; 
     FD_ZERO(&fdr); 
     FD_SET(nwsock, &fdr); 

     struct timeval to; 
     to.tv_sec = 5; 
     to.tv_usec = 0; 

     n = select(newsock+1, &fdr, NULL, NULL, &to); 
     if (n <= 0) 
     { 
      // error/timeout 
      break; 
     } 

     continue; 
    } 

    if (n == 0) 
    { 
     // disconnected 
     break; 
    } 

    if ((datalen + n) > datacap) 
    { 
     datacap = ((datalen + n) + (sizeof(buf)-1)) & ~(sizeof(buf)-1); 
     // or: 
     // datacap = (((datalen + n) + sizeof(buf))/sizeof(buf)) * sizeof(buf); 

     temp = realloc(data, datacap); 
     if (temp == NULL) 
     { 
      // error 
      break; 
     } 

     data = temp; 
    } 

    memcpy(data + datalen, buf, n); 
    datalen += n; 

    printf("%*.*s", n, n, buf); 
} 
while (1); 
... 
if (data) free(data); 
+0

。为什么你在下面使用这个值进行分析?这意味着这一行:'datacap =((datalen + n)+(sizeof(buf)-1))&〜(sizeof(buf)-1);' – amidnikmal

+0

'select()'返回-1发生,如果超时过去了0,并且如果有任何描述符被发信号,则发生> 0。由于只有1个描述符被传入,所以返回> 0意味着套接字在5秒内变得可读,所以再次调用'recvfrom()',否则意味着套接字不可读,请停止尝试。至于'datacap'的计算,它将'datalen + n'(已存在于缓冲区中的数据和已读取的新数据)和求和到四舍五入到sizeof(buf)的下一个最高偶数倍数, '。 –

相关问题