我正在使用libcurl并从我的http服务器复制内容。我需要获取段并将获取的段保存在新文件中。
第一个段是正确获取的,但是第二个段有第一个段的内容附加到它,它不应该。
在将第一个段复制到我的文件后,应释放内存,但不会发生。
附上部分代码:
//code
char *m_pBuffer = NULL;
size_t m_Size = 0;
void* Realloc(void* ptr, size_t size)
{
if(ptr)
return realloc(ptr, size);
else
return malloc(size);
};
// Callback must be declared static, otherwise it won't link...
size_t WriteMemoryCallback(char* ptr, size_t size, size_t nmemb)
{
// Calculate the real size of the incoming buffer
size_t realsize = size * nmemb;
// (Re)Allocate memory for the buffer
m_pBuffer = (char*) realloc(m_pBuffer, m_Size + realsize);
// Test if Buffer is initialized correctly & copy memory
if (m_pBuffer == NULL) {
realsize = 0;
}
memcpy(&(m_pBuffer[m_Size]), ptr, realsize);
m_Size += realsize;
// return the real size of the buffer...
return realsize;
};
namespace ahs
{
/* Construction / Initialisation */
{
return 0;
}
{
curlpp::Cleanup cleaner;
curlpp::Easy request;
// Set the writer callback to enable cURL
// to write result in a memory area
curlpp::types::WriteFunctionFunctor functor(WriteMemoryCallback);
curlpp::options::WriteFunction *test = new curlpp::options::WriteFunction(functor);
request.setOpt(test);
// Setting the URL to retrive.
string abc = "http://192.168.0.34/ahs-1.0/example/ingest";
string kk= abc + tobeused;
request.setOpt(new curlpp::options::Url(kk));
request.setOpt(new curlpp::options::Verbose(true));
request.perform();
print();
}
catch ( curlpp::LogicError & e )
{
std::cout << e.what() << std::endl;
}
catch ( curlpp::RuntimeError & e )
{
std::cout << e.what() << std::endl;
}
FILE *fp;
if((fp = fopen(pp, "wb")) == NULL) {
printf("Cannot open file.\n");
exit(1);
}
if( fwrite(m_pBuffer, (long)m_Size, 1, fp) != 1) {
printf("Write Error.\n");
exit(1);
}
fclose(fp);
free(m_pBuffer);
答案 0 :(得分:2)
首先,您正在使用C ++。使用std::vector
来处理缓冲区,然后这个问题就消失了。
其次,你有一个名为Realloc
但正在调用realloc
的函数,这是故意的吗?
答案 1 :(得分:2)
这是一个非常危险的电话:
// (Re)Allocate memory for the buffer
m_pBuffer = (char*) realloc(m_pBuffer, m_Size + realsize);
如果realloc返回NULL,则m_pBuffer最初指向的数据将丢失:您没有指向它的任何内容,并且您无法再释放它。
顺便说一下,你可以使用带有附加的std :: vector而不是reallocs,如果你不需要连续的缓冲区,你可以使用带有附加的std :: deque,这对于大缓冲区更有效,当然,你也可以使用std :: string,即使你正在编写一些空字节。重新分配你的方式的问题是它会每次重新分配并移动你所有的内存,它最终会结束O(N ^ 2)。
您应该能够获得估计的大小。顺便说一句,如果您只想将其写入持久性,那么您是不是一次只能将其作为缓冲区,而不是先将其全部加载到内存中?
(我认为这可能是你想要做的但不是)。
答案 2 :(得分:1)
你的memcpy
正在进行附加......
memcpy(&(m_pBuffer[m_Size]), ptr, realsize);
所以你重新分配缓冲区(扩展),并没有像你期望的那样清理缓冲区,它会将内容留在那里,而进入重新分配的空间,你复制新的内容......你感到惊讶吗?你从某个地方复制了代码吗?
答案 3 :(得分:0)
据我所知,你得到的是你所要求的。 您分配一些内存(第一个块的大小)并用第一个块填充它。
然后将此内存的大小增加为第一个和第二个块的大小,并在第一个块之后用第二个块填充它,以便内存包含第一个和第二个块。
如果最后一次写出这个内存,这很好。如果你在每个块之后写出来,那么你需要记住你在内存块中的位置,或者只是为每个块分配内存,填充它,写出然后释放它。
答案 4 :(得分:0)
您只需在每个获取的片段后放置m_Size=0;
。