Этот вопрос немного длинный из-за исходного кода, который я попытался максимально упростить. Пожалуйста, потерпите меня и спасибо, что читаете вместе с нами.
У меня есть приложение с циклом, который может выполняться миллионы раз. Вместо нескольких тысяч или миллионов вызовов malloc
/free
в этом цикле я хотел бы сделать один malloc
заранее, а затем от нескольких тысяч до миллионов вызовов realloc
.
Но я столкнулся с проблемой, когда мое приложение потребляет несколько ГБ памяти и убивает себя, когда я использую realloc
. Если я использую malloc
, мое использование памяти в порядке.
Если я запускаю меньшие наборы тестовых данных с memtest valgrind
, он не сообщает об утечках памяти ни с malloc
, ни с realloc
.
Я проверил, что сопоставляю каждый объект с malloc
-ed (а затем realloc
-ed) с соответствующим free
.
Итак, теоретически у меня нет утечки памяти, просто использование realloc
, похоже, потребляет всю доступную мне оперативную память, и я хотел бы знать, почему и что я могу сделать, чтобы это исправить.
Сначала у меня было что-то вроде этого, которое использует malloc
и работает правильно:
Код Malloc
void A () {
do {
B();
} while (someConditionThatIsTrueForMillionInstances);
}
void B () {
char *firstString = NULL;
char *secondString = NULL;
char *someOtherString;
/* populate someOtherString with data from stream, for example */
C((const char *)someOtherString, &firstString, &secondString);
fprintf(stderr, "first: [%s] | second: [%s]\n", firstString, secondString);
if (firstString)
free(firstString);
if (secondString)
free(secondString);
}
void C (const char *someOtherString, char **firstString, char **secondString) {
char firstBuffer[BUFLENGTH];
char secondBuffer[BUFLENGTH];
/* populate buffers with some data from tokenizing someOtherString in a special way */
*firstString = malloc(strlen(firstBuffer)+1);
strncpy(*firstString, firstBuffer, strlen(firstBuffer)+1);
*secondString = malloc(strlen(secondBuffer)+1);
strncpy(*secondString, secondBuffer, strlen(secondBuffer)+1);
}
Это прекрасно работает. Но я хочу что-то быстрее.
Теперь я тестирую realloc
аранжировку, которая malloc
только один раз:
Код Realloc
void A () {
char *firstString = NULL;
char *secondString = NULL;
do {
B(&firstString, &secondString);
} while (someConditionThatIsTrueForMillionInstances);
if (firstString)
free(firstString);
if (secondString)
free(secondString);
}
void B (char **firstString, char **secondString) {
char *someOtherString;
/* populate someOtherString with data from stream, for example */
C((const char *)someOtherString, &(*firstString), &(*secondString));
fprintf(stderr, "first: [%s] | second: [%s]\n", *firstString, *secondString);
}
void C (const char *someOtherString, char **firstString, char **secondString) {
char firstBuffer[BUFLENGTH];
char secondBuffer[BUFLENGTH];
/* populate buffers with some data from tokenizing someOtherString in a special way */
/* realloc should act as malloc on first pass through */
*firstString = realloc(*firstString, strlen(firstBuffer)+1);
strncpy(*firstString, firstBuffer, strlen(firstBuffer)+1);
*secondString = realloc(*secondString, strlen(secondBuffer)+1);
strncpy(*secondString, secondBuffer, strlen(secondBuffer)+1);
}
Если я посмотрю на вывод free -m
в командной строке, когда я запускаю этот тест на основе realloc
с большим набором данных, который вызывает условие миллиона циклов, моя память уменьшится с 4 ГБ до 0, и приложение вылетит.
Что мне не хватает в использовании realloc
, что вызывает это? Извините, если это глупый вопрос, и заранее спасибо за ваш совет.