繁体   English   中英

C ++:内存未由free()释放

[英]c++: memory not freed by free()

我正在使用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);

首先,您正在使用C ++。 使用std::vector处理您的缓冲区,然后这个问题就消失了。

其次,你有一个调用的函数Realloc而是要求realloc ,这是故意的吗?

这是一个非常危险的电话:

   // (Re)Allocate memory for the buffer
    m_pBuffer = (char*) realloc(m_pBuffer, m_Size + realsize);

如果realloc返回NULL,则最初由m_pBuffer指向的数据将丢失:您没有指向它的数据,您将无法再释放它。

顺便说一句,您可以使用带有附加的std :: vector而不是进行重新分配,并且如果您不需要连续的缓冲区,可以使用带有附加的std :: deque,这对于大型缓冲区特别有效,并且您可以当然,即使您正在写一些空字节,也要使用std :: string。

重新分配您执行操作的方式的问题是,它将每次都进行重新分配并移动所有内存,并且最终会导致O(N ^ 2)。

您应该能够获得估计的大小。 顺便说一句,如果您要做的只是将其写入持久性中,您是否可以一次不做一个缓冲区,并且不先将其全部加载到内存中?

(我认为这可能是您正在尝试做的事情,但不是)。

您在其中有一个memcpy正在执行附加操作...

memcpy(&(m_pBuffer[m_Size]), ptr, realsize);

因此,您重新分配了缓冲区(扩展),但并没有按预期的那样清理缓冲区,而是将内容留在那里,然后将其放入重新分配的空间中,然后复制到新内容中……您感到惊讶吗? 您是否从某处复制了代码?

据我所知,您正在得到想要的东西。 您分配一些内存(第一个块的大小),并用第一个块填充它。

然后,您将该内存的大小增加到第一个和第二个块的大小,并在第一个块之后立即填充第二个块,以便您的内存中包含第一个和第二个块。

如果最后一次写出此内存,这很好。 如果在每个块之后将其写出,则需要记住您在内存块中的位置,或者只是为每个块分配内存,将其填充,写出然后释放它。

您只需要输入m_Size=0; 在每个获取的段之后。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM