C ++ casted realloc导致内存泄漏

时间:2010-05-13 05:01:53

标签: c++ casting realloc

我正在使用我发现here的功能,通过cURL将网页保存到内存中:

struct WebpageData {
    char *pageData;
    size_t size;
};

size_t storePage(void *input, size_t size, size_t nmemb, void *output) {
    size_t realsize = size * nmemb;

    struct WebpageData *page = (struct WebpageData *)output;

    page->pageData = (char *)realloc(page->pageData, page->size + realsize + 1);
    if(page->pageData) {
        memcpy(&(page->pageData[page->size]), input, realsize);
        page->size += realsize;
        page->pageData[page->size] = 0;
    }

    return realsize;
}

找到这一行:

page->pageData = (char *)realloc(page->pageData, page->size + realsize + 1);

导致每次调用几百字节的内存泄漏。我从原始源中做出的唯一真正的改变是将有问题的行转换为(char *),我的编译器(gcc,g ++特别是如果它是ac / c ++问题,但是gcc也不能用uncast编译)声明)坚持,但我认为这是泄漏的来源。任何人都可以澄清吗?

由于

3 个答案:

答案 0 :(得分:1)

您发布的代码(据我所知)是正确的。如果它在泄漏,我 怀疑你在某个时刻忘记了free()内存块。 如果不能简单地允许realloc创建一个全新的内存块 扩展现有的,这是你感兴趣的。当然也允许分配比需要更大的块,这可能导致幻像泄漏。

现在,既然你正在使用C ++,我不得不问:你为什么不使用它 而是std::vector

struct WebpageData {
    std::vector<char> pageData;
    size_t size;
};

size_t storePage(void *input, size_t size, size_t nmemb, void *output) {
    size_t realsize = size * nmemb;
    WebpageData *page = reinterpret_cast<WebpageData *>(output);

    page->pageData.resize(page->size + realsize + 1);
    memcpy(&(page->pageData[page->size]), input, realsize);
    page->size += realsize;
    page->pageData[page->size] = 0;

    return realsize;
}

答案 1 :(得分:0)

如果在* nix上进行开发,一般来说我会尝试使用valgrind(http://valgrind.org/)运行程序来解决内存泄漏问题(在这种情况下,我认为你确实知道内存的分配位置,但它在哪里被释放?)。在这种情况下,我建议不要在c ++程序中使用malloc,realloc和其他类似的c内存管理,除非绝对必要且不可避免。应该避免使用c ++内存管理工具,在这种情况下,我认为内存没有正确释放。使用c ++ Vectors可能会让你的生活变得更轻松,因为你不必担心数组的大小调整并跟踪内存分配的所有变化。

答案 2 :(得分:0)

演员不应该与realloc有任何不同。你确定你有内存泄漏吗?代码正在追加数据,所以如果你每次要求它存储三次1kB的数据,那么它将存储3kB。这是您复制和粘贴代码时的意图吗?当然,当你完成它时,你必须在某处释放()块。

其他想法:

  • 您重新分配的内存最初是malloc'd还是realloc'd?

  • 请注意,如果您无法重新分配数据,则会丢失所有数据。如果你重新分配到一个临时指针然后只覆盖page-&gt; pageData,如果它是有效的,这将不会发生,你将能够向调用者报告失败(尽管这在实践中不太可能发生)如果有的话,你可能会遇到更大的问题!)

  • 每次收到新数据时都会重新分配该块。分配比所需更大的块,将数据检索到其中,然后仅在接收到所有数据后将其重新分配到精确拟合块中可能会更有效,这样可以避免重复重新分配块。