我正在开发的应用程序出现问题。在这个程序中,我必须从文本文件中读取大量(数十亿)数据并对其进行管理,但由于这是一个两个学生的项目,阅读部分将由我的伙伴开发。出于测试原因,我写了一个小程序,生成伪随机结构来代替我的伙伴会做的事情。
问题如下:为了释放内存,可以丢弃大量生成的数据(由于冗余)。但即使调用free()函数,内存使用量也在不断增长。所以我尝试开发一个调试应用程序,它只生成一大块数据并立即释放它。并重复了数千次。 好吧,我无法理解原因,但分配给该进程的内存增长到~1.8 GB ram然后崩溃。为什么?最奇怪的是,这让我有很多我不太了解的事情,就是当进程崩溃时,malloc不返回NULL指针,因为当readCycles == 6008并且绕过NULL检查时进程总是崩溃。 / p>
我已经在StackOverflow上阅读了其他相关主题,我理解为什么free()不会减少分配给我的进程的内存。没关系。但为什么内存使用量不断增长? malloc不应该分配以前释放的内存而不是不断地请求新的内存吗?
这是我的代码中最相关的部分:
#define NREAD 1000
#define READCYCLES 10000
#define N_ALPHA_ILLUMINA 7
#define N_ALPHA_SOLID 5
#define SEQLEN 76
typedef struct{
char* leftDNA;
char* leftQuality;
unsigned long int leftRow;
char* rightDNA;
char* rightQuality;
unsigned long int rightRow;
} MatePair;
unsigned long int readCycles = 0;
MatePair* readStream(MatePair* inputStream, short* eof, unsigned long int* inputSize){
double r;
unsigned long int i, j;
unsigned long int leftRow;
int alphabet[] = {'A', 'C', 'G', 'T', 'N'};
inputStream = (MatePair*) malloc (sizeof(MatePair) * (NREAD + 1));
printf("%d\n", readCycles);
if (inputStream == NULL){
(*eof) = 1;
return;
}
for (i = 0; i < NREAD; i++){
leftRow = readCycles * NREAD + i;
inputStream[i].leftDNA = (char*) malloc (SEQLEN);
inputStream[i].rightDNA = (char*) malloc (SEQLEN);
inputStream[i].leftQuality = (char*) malloc (SEQLEN);
inputStream[i].rightQuality = (char*) malloc (SEQLEN);
for (j = 0; j < SEQLEN; j++){
r = rand() / (RAND_MAX + 1);
inputStream[i].leftDNA[j] = alphabet[(int)(r * 5)];
inputStream[i].rightDNA[j] = alphabet[(int)(r * 5)];
inputStream[i].leftQuality[j] = (char) 64 + (int)(r * 60);
inputStream[i].rightQuality[j] = (char) 64 + (int)(r * 60);
}
inputStream[i].leftDNA[SEQLEN - 1] = '\0';
inputStream[i].rightDNA[SEQLEN - 1] = '\0';
inputStream[i].leftQuality[SEQLEN - 1] = '\0';
inputStream[i].rightQuality[SEQLEN - 1] = '\0';
inputStream[i].leftRow = leftRow;
inputStream[i].rightRow = leftRow;
}
inputStream[i].leftRow = -1;
readCycles++;
(*inputSize) = NREAD;
(*eof) = readCycles > READCYCLES;
return inputStream;
}
int main(int argc, char* argv[]){
short eof = 0;
unsigned long int inputSize = 0;
MatePair* inputStream = NULL;
while (!eof){
inputStream = readStream(inputStream, &eof, &inputSize);
free(inputStream);
inputStream = NULL;
}
return 0;
}
我忘了提到这一点,但在发布之前,我没有调用free(inputStream),而是尝试调用freeMemory(inputStream)。不过,不确定这是否是正确的做法。
void freeMemory(MatePair* memblock){
for ( ; memblock->leftRow != 1; memblock++){
free(memblock -> leftDNA);
free(memblock -> leftQuality);
free(memblock -> rightDNA);
free(memblock -> rightQuality);
}
}
答案 0 :(得分:3)
内存泄漏。多少&#39; malloc()&#39;你打过电话,有多少人免费()&#39;你必须用来释放堆上所有已分配的内存。
因此,
inputStream[i].leftDNA = (char*) malloc (SEQLEN);
inputStream[i].rightDNA = (char*) malloc (SEQLEN);
inputStream[i].leftQuality = (char*) malloc (SEQLEN);
inputStream[i].rightQuality = (char*) malloc (SEQLEN);
这些&#39; malloc()&#39;函数必须与free()配对。
答案 1 :(得分:2)
你没有释放在读取循环中分配的所有成员,因此你正在失去内存eahc时间。请记住,您必须释放使用malloc分配的所有内容,而不仅仅是阵列。
好的,看看你的编辑,你的freeMemory仍然是错误的。试试这个;
void freeMemory(MatePair* inputStream)
{
for (i = 0; i < NREAD; i++){
free(inputStream[i].leftDNA);
free(inputStream[i].leftQuality);
free(inputStream[i].rightDNA);
free(inputStream[i].rightQuality);
}
free (inputStream);
}
你的自由(memblock)在循环中,它不应该是,并且我倾向于使用与mallocing相同的迭代序列。您还需要在每个malloc之后进行错误检查,并在此时决定如何处理NULL。