2013-09-23 43 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)的下一個最高偶數倍數, '。 –

相關問題