C ++ Rated Realloc вызывает утечку памяти
Вопрос
Я использую функцию, которую я нашел здесь Чтобы сохранить веб-страницу в память с завитым:
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 его в точный блок подходит только после того, как все данные получают, чтобы вы избегаете неоднократно перенаправить блока.