Вопрос

Я использую функцию, которую я нашел здесь Чтобы сохранить веб-страницу в память с завитым:

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);

вызывает утечку памяти несколько сотен байтов на звонок. Единственное реальное изменение, которое я сделал из первоначального источника, вызывает под сомнение линию к A (CHAR *), который мой компилятор (GCC, G ++ конкретно, если это проблема AC / C ++, но GCC также не скомпилируется с помощью Uncast Заявление) настаивало, но я предполагаю, что это источник утечки. Может кто-нибудь выяснить?

Спасибо

Это было полезно?

Решение

Код, который вы опубликовали (насколько я могу сказать), правильно. Если это утечка, я подозреваю, что вы забываете 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;
}

Другие советы

При разработке * NIX вообще говоря, я бы попробовал запустить программу с VALGRIND (http://valgrind.org/) Для утечки памяти вознаграждаются проблемы (в этом случае я думаю, что вы знаете, где присваивается память, но где она освобождается?). В этом случае я бы предложил не использовать Malloc, Realloc и другую подобное управление памятью C в программе C ++, если не абсолютно необходимые и неизбежные. Их следует избегать в пользу использования инструментов управления памятью C ++, в этом случае я думаю, что память не освобождается должным образом. Использование векторов C ++, скорее всего, сделает вашу жизнь здесь намного проще, так как вам не нужно беспокоиться о размерах массива и отслеживания всех изменений в распределении памяти.

Ступень не должен иметь никакого различия в Realloc. Вы уверены, что у вас есть утечка памяти? Кодекс добавляет данные, поэтому, если вы просили его вработать три раза в три раза с 1 КБ данных каждый раз, он будет хранить 3КБ. Это то, что вы намереваетесь, когда вы скопировали и вставляли код? И, конечно, вы должны освободить () блок где-то, когда вы закончите с ним.

Другие мысли:

  • Была ли память, которую вы перерезаете изначально Malloc'd или Realloc'd?

  • Обратите внимание, что если вы не можете Realoc Data, вы все потеряете. Если вы Realoc во временный указатель, а затем только перезаписи страницы-> Pagerata, если это действительно, это не произойдет, и вы сможете сообщить об ошибке абонента (хотя это очень вряд ли произойдет на практике, И у вас, вероятно, имели гораздо большие проблемы, если это делает!)

  • Вы перенимаете блок каждый раз, когда вы получаете новые данные. Это, вероятно, будет более эффективно выделить больший блок, чем требуется, извлеките его в него данные, а затем Realloc его в точный блок подходит только после того, как все данные получают, чтобы вы избегаете неоднократно перенаправить блока.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top