我仍然在提高我的C编码技能,并继续遇到妥善管理内存的问题 - 如图所示。无论如何,我正在从套接字读取,只要我从套接字的总响应长度不超过我的缓冲区大小我就可以了。我知道这一点,因为当我将缓冲区大小增加到足以容纳传入数据时,它对于较大的有效负载效果很好。显然,在堆栈上创建一个非常大的“just-in-case”缓冲区是不可行的,所以我想在堆上动态增长缓冲区。这就是我目前正在做的事情:
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改为大于我的总输入数据大小。
似乎它可能只是我忽略的一些简单。有什么想法吗?
答案 0 :(得分:2)
问题在于以下几点:
memcpy(raw_response+previousLength, in_buf, retcode);
previousLength = retcode;
您的函数将适用于第一次和第二次迭代,但之后将开始破坏数据。我假设您打算写previousLength += retcode;
代码中还存在其他一些问题,而这些问题并不是您问题的答案。首先,如果realloc或malloc失败会发生什么?你不要在你的小样本中检查这个。此外,您总是可以使用realloc(如果指针为NULL,则会像malloc一样,请参阅this SO问题)。即。
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,这将再次引起问题)。