1

我需要从套接字接收 recv() 数据并将其存储到缓冲区中,但我需要确保获取所有数据,以便循环使用。因此,为了确保缓冲区中的空间不会用完,我尝试使用 realloc 来调整分配给缓冲区的内存大小。到目前为止,我有:

 // receive response
 int i = 0;
 int amntRecvd = 0;
 char *pageContentBuffer = (char*) malloc(4096 * sizeof(char));
 while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
  i += amntRecvd;
  realloc(pageContentBuffer, 4096 + sizeof(pageContentBuffer));
 }

但是,这似乎无法正常工作,因为 Valgrind 抱怨“valgrind:‘不可能’发生了:”。关于如何正确完成此操作的任何建议?

谢谢, 赫里斯托

更新...我意识到我使用 realloc 不正确。这是一个修订版:

 int i = 0;
 int amntRecvd = 0;
 char *pageContentBuffer = (char*) malloc(4096 * sizeof(char));
 while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
  i += amntRecvd;
  char *temp = realloc(pageContentBuffer, 4096 + sizeof(pageContentBuffer));
  if (temp != NULL) {
   pageContentBuffer = temp;
  }
 }

然而,valgrind 仍然在抱怨:

==25812== Syscall param socketcall.recvfrom(buf) points to unaddressable byte(s)
==25812==    at 0x33B880DAA1: recv (in /lib64/libpthread-2.5.so)
==25812==    by 0x401D78: tunnelURL (proxy.c:371)
==25812==    by 0x40142A: client_thread (proxy.c:194)
==25812==    by 0x33B8806616: start_thread (in /lib64/libpthread-2.5.so)
==25812==    by 0x33B7CD3C2C: clone (in /lib64/libc-2.5.so)
==25812==  Address 0x5642768 is 0 bytes after a block of size 4,104 alloc'd
==25812==    at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==25812==    by 0x401D47: tunnelURL (proxy.c:373)
==25812==    by 0x40142A: client_thread (proxy.c:194)
==25812==    by 0x33B8806616: start_thread (in /lib64/libpthread-2.5.so)
==25812==    by 0x33B7CD3C2C: clone (in /lib64/libc-2.5.so)
4

4 回答 4

3

除了@whirlwind 所说的,还有第二个问题:

sizeof不返回先前分配的内存量,它实际上是一个编译时构造,相当于sizeof(char *),即字符指针的大小。

您需要在变量中手动跟踪缓冲区的长度。没有标准的方法来“询问”malloc/realloc 分配了多少内存。

于 2010-04-21T01:26:44.440 回答
2

也许有一个问题,因为您误用了 realloc()。您需要查看它是否返回一个新指针,如果是,则存储该指针。

// receive response
int i = 0;
int amntRecvd = 0;
char *pageContentBuffer = (char*) malloc(4096 * sizeof(char));
while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
    i += amntRecvd;
    pageContentBuffer = realloc(pageContentBuffer, 4096 + sizeof(pageContentBuffer));
}
于 2010-04-21T01:19:53.440 回答
1

查找 realloc

sizeof是编译时值,而不是运行时值。

realloc返回 0是可能的。

尝试这个...

// receive response
int i = 0;
int amntRecvd = 0;
int currentSize = 4096;
int oldSize = currentSize;
char *pageContentBuffer = (char*) malloc(currentSize);
while ((amntRecvd = recv(proxySocketFD, pageContentBuffer + i, 4096, 0)) > 0) {
    i += amntRecvd;
    oldSize = currentSize; 
    currentSize += 4096; 
    char *newBuffer = malloc(currentSize); 
    memcpy(newBuffer,pageContentBuffer,oldSize); 
    free(pageContentBuffer); 
    pageContentBuffer = newBuffer;
}

最好的办法是重新分配、复制然后显式释放内存——realloc这很古怪。

于 2010-04-21T01:27:26.413 回答
1

您的主要问题是您重新分配了错误的内存量。你要

realloc(pageContentBuffer, 4096 + i);

sizeof(pageContentBuffer)is just sizeof(char *),这意味着您重新分配的空间远远少于第二次阅读所需的空间。

于 2010-04-21T02:46:24.830 回答