为什么realloc吃了大量的记忆?

Ale*_*lds 3 c malloc realloc

这个问题有点长,因为源代码,我试图尽可能简化.请耐心等待,并感谢您的阅读.

我有一个循环的应用程序可能运行数百万次.而不是在该循环中的数千到数百万malloc/次free呼叫,我想先做一个malloc,然后做几千到几百万次realloc呼叫.

但是当我使用时,我遇到了一个问题,即我的应用程序消耗了几GB的内存并自行杀死realloc.如果我使用malloc,我的内存使用情况很好.

如果我在较小的测试数据集运行valgrind的内存测试,它报告没有内存泄漏有两种mallocrealloc.

我已经验证我将每个malloc-ed(然后是realloc-ed)对象与相应的匹配free.

所以,从理论上讲,我并没有泄漏内存,只是使用realloc似乎消耗了我所有可用的RAM,我想知道为什么以及我能做些什么来解决这个问题.

我最初的东西是这样的,使用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);
}
Run Code Online (Sandbox Code Playgroud)

这很好用.但我想要更快的东西.

现在我测试一个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);
}
Run Code Online (Sandbox Code Playgroud)

如果我查看free -m命令行的输出,而我运行这个realloc基于大数据集导致百万循环条件的测试,我的内存从4 GB下降到0并且应用程序崩溃.

我错过了使用realloc它的原因是什么?对不起,如果这是一个愚蠢的问题,并提前感谢您的建议.

MSN*_*MSN 8

realloc如果无法在适当的位置进行调整大小操作,则必须将内容从旧缓冲区复制到新缓冲区.如果您不需要保留原始内存,则A malloc/ freepair可能比a更好realloc.

这就是为什么realloc暂时需要比malloc//更多的内存free.你也通过不断交错来鼓励碎片化realloc.即,你基本上是这样做的:

malloc(A);
malloc(B);

while (...)
{
    malloc(A_temp);
    free(A);
    A= A_temp;
    malloc(B_temp);
    free(B);
    B= B_temp;
}
Run Code Online (Sandbox Code Playgroud)

而原始代码确实:

while (...)
{
    malloc(A);
    malloc(B);
    free(A);
    free(B);
}
Run Code Online (Sandbox Code Playgroud)

在每个第二个循环结束时,你已经清理了你使用的所有内存; 这种情况更有可能将全局内存堆返回到干净状态,而不是通过交错内存分配而不完全释放所有内存堆.