这个问题有点长,因为源代码,我试图尽可能简化.请耐心等待,并感谢您的阅读.
我有一个循环的应用程序可能运行数百万次.而不是在该循环中的数千到数百万malloc/次free呼叫,我想先做一个malloc,然后做几千到几百万次realloc呼叫.
但是当我使用时,我遇到了一个问题,即我的应用程序消耗了几GB的内存并自行杀死realloc.如果我使用malloc,我的内存使用情况很好.
如果我在较小的测试数据集运行valgrind的内存测试,它报告没有内存泄漏有两种malloc或realloc.
我已经验证我将每个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它的原因是什么?对不起,如果这是一个愚蠢的问题,并提前感谢您的建议.
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)
在每个第二个循环结束时,你已经清理了你使用的所有内存; 这种情况更有可能将全局内存堆返回到干净状态,而不是通过交错内存分配而不完全释放所有内存堆.