0

我仍在完善我的 C 编码技能,并不断遇到正确管理内存的问题——去看看吧。无论如何,我正在从套接字读取,只要我从套接字的总响应长度不大于我的缓冲区大小就可以了。我知道这一点是因为当我将缓冲区大小增加到足够大以容纳传入数据时,它对于较大的有效负载就可以正常工作。显然,在堆栈上创建一个非常大的“以防万一”缓冲区是不可行的,所以我想在堆上动态增长缓冲区。这是我目前正在做的事情:

raw_response = NULL;

// Receive from the Web server
retcode = recv(server_s, in_buf, BUF_SIZE, 0);

while ((retcode > 0) || (retcode == -1))
{
  totalLength += retcode;

  if (raw_response == NULL) {
    raw_response = (char*)malloc(sizeof(char)*totalLength);
    memcpy(raw_response, in_buf, totalLength);
  } else {
    raw_response = (char*)realloc(raw_response, sizeof(char)*totalLength);
    memcpy(raw_response+previousLength, in_buf, retcode);
  }

  previousLength = retcode;
  retcode = recv(server_s, in_buf, BUF_SIZE, 0);
  if (retcode == 0 || retcode == -1) {
    printf("\n\nNo more data, bailing. Data length was: %lu\n\n", totalLength);
  }
}

如果 raw_response 为 NULL,我知道我还没有收到任何数据,所以我使用 malloc。否则,我使用 realloc,这样我就不必建立一个新的缓冲区。相反,我可以附加传入的数据。因此,为了在第一次迭代后获取现有数据的结尾,我获取 raw_response 的地址并将先前的长度添加到该地址中,并将新数据附加到那里,假设它在每次后续调用 recv() 时都正确附加。

问题是我的最终缓冲区总是损坏,除非我将 BUF_SIZE 更改为大于我的总传入数据大小的值。

似乎这可能只是我忽略的一些简单的事情。有什么想法吗?

4

1 回答 1

2

问题是这些行:

memcpy(raw_response+previousLength, in_buf, retcode);
previousLength = retcode;

您的函数将适用于第一次和第二次迭代,但之后将开始破坏数据。我假设你打算写previousLength += retcode;

代码还有一些其他问题不是您问题的答案。首先,如果 realloc 或 malloc 失败会发生什么?你没有在你的小样本中检查这个。此外,您始终可以只使用 realloc (如果指针为 NULL,则其作用类似于 malloc ,请参阅SO 问题)。IE

char *tmp = realloc(raw_response, sizeof(*tmp) * totalLength);
if (tmp == NULL)
     return -ENOMEM;
raw_response = tmp;
memcpy(raw_response + previousLength, in_buf, ret_code)

其次,当 ret_code 为 -1 时,您可能会调用 memcpy(也将 totalLength 更改为 -1,这将再次导致问题)。

于 2013-06-20T01:41:32.387 回答